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..765db89daa 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -28,7 +28,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,7 +39,10 @@ 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'], @@ -98,9 +101,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 a5d740d017..b907eae73c 100644 --- a/package.json +++ b/package.json @@ -5,18 +5,18 @@ "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/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/preset-env": "^7.11.0", + "autoprefixer": "^9.8.6", "babel-eslint": "^11.0.0-beta.2", "babel-loader": "^8.0.6", - "browser-sync": "^2.26.10", + "browser-sync": "^2.26.12", "copy-webpack-plugin": "^5.1.1", - "css-loader": "^4.0.0", + "css-loader": "^4.1.1", "cssnano": "^4.1.10", "del": "^5.1.0", "eslint": "^6.8.0", @@ -48,7 +48,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 +62,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 +76,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", @@ -115,6 +114,8 @@ "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", @@ -138,6 +139,7 @@ "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 +147,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", @@ -161,7 +165,7 @@ "src/controllers/session/forgotPassword/index.js", "src/controllers/session/redeemPassword/index.js", "src/controllers/session/login/index.js", - "src/controllers/sessopm/selectServer/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 +177,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", @@ -197,6 +207,7 @@ "src/controllers/playback/queue/index.js", "src/controllers/playback/video/index.js", "src/controllers/searchpage.js", + "src/controllers/livetvtuner.js", "src/controllers/shows/episodes.js", "src/controllers/shows/tvgenres.js", "src/controllers/shows/tvlatest.js", @@ -210,7 +221,6 @@ "src/controllers/user/playback/index.js", "src/controllers/user/profile/index.js", "src/controllers/user/subtitles/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", @@ -254,6 +264,8 @@ "src/scripts/imagehelper.js", "src/scripts/inputManager.js", "src/scripts/keyboardNavigation.js", + "src/scripts/libraryBrowser.js", + "src/scripts/multiDownload.js", "src/scripts/playlists.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", @@ -275,7 +287,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", @@ -283,6 +295,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/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/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..9834255003 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'; @@ -69,6 +68,7 @@ import 'listViewStyle'; const minDate = new Date(); const hasUserId = 'false' !== elem.getAttribute('data-useractivity'); + // 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 7af7ed4a95..4fa2a92433 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -153,20 +153,14 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro }; 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 +191,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 +202,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro showForcedLogoutMessage(globalize.translate('AccessRestrictedTryAgainLater')); appRouter.showLocalLogin(apiClient.serverId()); } - } } } @@ -237,12 +228,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 +244,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } function onApiClientCreated(e, newApiClient) { - newApiClient.normalizeImageOptions = normalizeImageOptions; if (browser.iOS) { @@ -269,12 +257,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 +276,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro var firstConnectionResult; function start(options) { - loading.show(); initApiClients(); @@ -302,53 +287,29 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro 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,7 +338,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } if (apiClient && apiClient.isLoggedIn()) { - console.debug('appRouter - user is authenticated'); if (route.isDefaultRoute) { @@ -385,11 +345,8 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro loadUserSkinWithOptions(ctx); return; } else if (route.roles) { - validateRoles(apiClient, route.roles).then(function () { - callback(); - }, beginConnectionWizard); return; } @@ -431,7 +388,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 +447,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } function getWindowLocationSearch(win) { - var currentPath = currentRouteInfo ? (currentRouteInfo.path || '') : ''; var index = currentPath.indexOf('?'); @@ -535,9 +490,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 +597,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..e7d5bbc2f4 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -105,6 +105,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 +259,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'); } @@ -297,7 +293,7 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g features.push('fileinput'); } - if (browser.chrome) { + if (browser.chrome || browser.edgeChromium) { features.push('chromecast'); } @@ -353,7 +349,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 () { diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index a6d0b10662..edb9db28ba 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -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..1521650ed0 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,9 +70,7 @@ import browser from 'browser'; } function getImgUrl({Id}, {ImageTag}, index, maxWidth, apiClient) { - if (ImageTag) { - return apiClient.getScaledImageUrl(Id, { maxWidth: maxWidth * 2, @@ -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..ba78ab99e1 100644 --- a/src/components/displaySettings/displaySettings.js +++ b/src/components/displaySettings/displaySettings.js @@ -55,7 +55,6 @@ import 'emby-button'; } function loadSoundEffects(context, userSettings) { - const selectSoundEffects = context.querySelector('.selectSoundEffects'); const options = pluginManager.ofType('soundeffects').map(plugin => { return { @@ -81,7 +80,6 @@ import 'emby-button'; } function loadSkins(context, userSettings) { - const selectSkin = context.querySelector('.selectSkin'); const options = pluginManager.ofType('skin').map(plugin => { @@ -108,7 +106,6 @@ import 'emby-button'; } function showOrHideMissingEpisodesField(context) { - if (browser.tizen || browser.web0s) { context.querySelector('.fldDisplayMissingEpisodes').classList.add('hide'); return; @@ -118,7 +115,6 @@ import 'emby-button'; } function loadForm(context, user, userSettings) { - if (user.Policy.IsAdministrator) { context.querySelector('.selectDashboardThemeContainer').classList.remove('hide'); } else { @@ -213,7 +209,6 @@ import 'emby-button'; } function saveUser(context, user, userSettingsInstance, apiClient) { - appSettings.runAtStartup(context.querySelector('.chkRunAtStartup').checked); user.Configuration.DisplayMissingEpisodes = context.querySelector('.chkDisplayMissingEpisodes').checked; diff --git a/src/components/favoriteitems.js b/src/components/favoriteitems.js index 38715043e7..358bf04112 100644 --- a/src/components/favoriteitems.js +++ b/src/components/favoriteitems.js @@ -154,8 +154,7 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad html += '
'; } - var supportsImageAnalysis = appHost.supports('imageanalysis'); - var cardLayout = (appHost.preferVisualCards || supportsImageAnalysis) && section.autoCardLayout && section.showTitle; + var cardLayout = appHost.preferVisualCards && section.autoCardLayout && section.showTitle; cardLayout = false; html += cardBuilder.getCardsHtml(result.Items, { preferThumb: section.preferThumb, diff --git a/src/components/fetchhelper.js b/src/components/fetchhelper.js index f626abefee..00bffc235a 100644 --- a/src/components/fetchhelper.js +++ b/src/components/fetchhelper.js @@ -1,6 +1,5 @@ /* eslint-disable indent */ export function getFetchPromise(request) { - const headers = request.headers || {}; if (request.dataType === 'json') { @@ -16,7 +15,6 @@ let contentType = request.contentType; if (request.data) { - if (typeof request.data === 'string') { fetchRequest.body = request.data; } else { @@ -27,7 +25,6 @@ } if (contentType) { - headers['Content-Type'] = contentType; } @@ -48,11 +45,9 @@ } function fetchWithTimeout(url, options, timeoutMs) { - console.debug(`fetchWithTimeout: timeoutMs: ${timeoutMs}, url: ${url}`); return new Promise(function (resolve, reject) { - const timeout = setTimeout(reject, timeoutMs); options = options || {}; @@ -65,7 +60,6 @@ resolve(response); }, function (error) { - clearTimeout(timeout); console.debug(`fetchWithTimeout: timed out connecting to url: ${url}`); diff --git a/src/components/filtermenu/filtermenu.js b/src/components/filtermenu/filtermenu.js index 936e2b0407..20399fb52d 100644 --- a/src/components/filtermenu/filtermenu.js +++ b/src/components/filtermenu/filtermenu.js @@ -2,19 +2,15 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', 'use strict'; function onSubmit(e) { - e.preventDefault(); return false; } function renderOptions(context, selector, cssClass, items, isCheckedFn) { - var elem = context.querySelector(selector); if (items.length) { - elem.classList.remove('hide'); - } else { elem.classList.add('hide'); } @@ -22,7 +18,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', var html = ''; html += items.map(function (filter) { - var itemHtml = ''; var checkedHtml = isCheckedFn(filter) ? ' checked' : ''; @@ -32,45 +27,20 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', itemHtml += ''; return itemHtml; - }).join(''); elem.querySelector('.filterOptions').innerHTML = html; } function renderDynamicFilters(context, result, options) { - - // If there's a huge number of these they will be really show to render - //if (result.Tags) { - // result.Tags.length = Math.min(result.Tags.length, 50); - //} - renderOptions(context, '.genreFilters', 'chkGenreFilter', result.Genres, function (i) { - // Switching from | to , var delimeter = (options.settings.GenreIds || '').indexOf('|') === -1 ? ',' : '|'; return (delimeter + (options.settings.GenreIds || '') + delimeter).indexOf(delimeter + i.Id + delimeter) !== -1; }); - - //renderOptions(context, '.officialRatingFilters', 'chkOfficialRatingFilter', result.OfficialRatings, function (i) { - // var delimeter = '|'; - // return (delimeter + (query.OfficialRatings || '') + delimeter).indexOf(delimeter + i + delimeter) != -1; - //}); - - //renderOptions(context, '.tagFilters', 'chkTagFilter', result.Tags, function (i) { - // var delimeter = '|'; - // return (delimeter + (query.Tags || '') + delimeter).indexOf(delimeter + i + delimeter) != -1; - //}); - - //renderOptions(context, '.yearFilters', 'chkYearFilter', result.Years, function (i) { - - // var delimeter = ','; - // return (delimeter + (query.Years || '') + delimeter).indexOf(delimeter + i + delimeter) != -1; - //}); } function loadDynamicFilters(context, options) { - var apiClient = connectionManager.getApiClient(options.serverId); var filterMenuOptions = Object.assign(options.filterMenuOptions, { @@ -81,16 +51,11 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', }); apiClient.getFilters(filterMenuOptions).then(function (result) { - renderDynamicFilters(context, result, options); - }, function () { - - // older server }); } function initEditor(context, settings) { - context.querySelector('form').addEventListener('submit', onSubmit); var elems = context.querySelectorAll('.simpleFilter'); @@ -98,7 +63,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', var length; for (i = 0, length = elems.length; i < length; i++) { - if (elems[i].tagName === 'INPUT') { elems[i].checked = settings[elems[i].getAttribute('data-settingname')] || false; } else { @@ -110,7 +74,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', elems = context.querySelectorAll('.chkVideoTypeFilter'); for (i = 0, length = elems.length; i < length; i++) { - elems[i].checked = videoTypes.indexOf(elems[i].getAttribute('data-filter')) !== -1; } @@ -118,7 +81,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', elems = context.querySelectorAll('.chkSeriesStatus'); for (i = 0, length = elems.length; i < length; i++) { - elems[i].checked = seriesStatuses.indexOf(elems[i].getAttribute('data-filter')) !== -1; } @@ -136,12 +98,10 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', } function saveValues(context, settings, settingsKey) { - var elems = context.querySelectorAll('.simpleFilter'); var i; var length; for (i = 0, length = elems.length; i < length; i++) { - if (elems[i].tagName === 'INPUT') { setBasicFilter(context, settingsKey + '-filter-' + elems[i].getAttribute('data-settingname'), elems[i]); } else { @@ -154,7 +114,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', elems = context.querySelectorAll('.chkVideoTypeFilter'); for (i = 0, length = elems.length; i < length; i++) { - if (elems[i].checked) { videoTypes.push(elems[i].getAttribute('data-filter')); } @@ -166,7 +125,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', elems = context.querySelectorAll('.chkSeriesStatus'); for (i = 0, length = elems.length; i < length; i++) { - if (elems[i].checked) { seriesStatuses.push(elems[i].getAttribute('data-filter')); } @@ -177,7 +135,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', elems = context.querySelectorAll('.chkGenreFilter'); for (i = 0, length = elems.length; i < length; i++) { - if (elems[i].checked) { genres.push(elems[i].getAttribute('data-filter')); } @@ -186,7 +143,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', } function setBasicFilter(context, key, elem) { - var value = elem.checked; value = value ? value : null; userSettings.setFilter(key, value); @@ -200,7 +156,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', } function moveCheckboxFocus(elem, offset) { - var parent = dom.parentWithClass(elem, 'checkboxList-verticalwrap'); var elems = focusManager.getFocusableElements(parent); @@ -225,7 +180,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', function onInputCommand(e) { switch (e.detail.command) { - case 'left': moveCheckboxFocus(e.target, -1); e.preventDefault(); @@ -244,7 +198,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', } function bindCheckboxInput(context, on) { - var elems = context.querySelectorAll('.checkboxList-verticalwrap'); for (var i = 0, length = elems.length; i < length; i++) { if (on) { @@ -256,11 +209,8 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', } FilterMenu.prototype.show = function (options) { - return new Promise(function (resolve, reject) { - require(['text!./filtermenu.template.html'], function (template) { - var dialogOptions = { removeOnClose: true, scrollY: false @@ -303,7 +253,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', bindCheckboxInput(dlg, true); dlg.querySelector('.btnCancel').addEventListener('click', function () { - dialogHelper.close(dlg); }); @@ -314,17 +263,10 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', 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 () { - bindCheckboxInput(dlg, false); if (layoutManager.tv) { @@ -332,7 +274,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', } if (submitted) { - //if (!options.onChange) { saveValues(dlg, options.settings, options.settingsKey); resolve(); diff --git a/src/components/focusManager.js b/src/components/focusManager.js index f2022cc445..9c495bf952 100644 --- a/src/components/focusManager.js +++ b/src/components/focusManager.js @@ -7,14 +7,12 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } function popScope(elem) { - if (scopes.length) { scopes.length -= 1; } } function autoFocus(view, defaultToFirst, findAutoFocusElement) { - var element; if (findAutoFocusElement !== false) { element = view.querySelector('*[autofocus]'); @@ -37,7 +35,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } function focus(element) { - try { element.focus({ preventScroll: scrollManager.isEnabled() @@ -50,16 +47,13 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { var focusableTagNames = ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON', 'A']; var focusableContainerTagNames = ['BODY', 'DIALOG']; var focusableQuery = focusableTagNames.map(function (t) { - if (t === 'INPUT') { t += ':not([type="range"]):not([type="file"])'; } return t + ':not([tabindex="-1"]):not(:disabled)'; - }).join(',') + ',.focusable'; function isFocusable(elem) { - if (focusableTagNames.indexOf(elem.tagName) !== -1) { return true; } @@ -83,7 +77,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } function focusableParent(elem) { - var originalElement = elem; while (!isFocusable(elem)) { @@ -101,7 +94,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { // Determines if a focusable element can be focused at a given point in time function isCurrentlyFocusableInternal(elem) { - // http://stackoverflow.com/questions/19669786/check-if-element-is-visible-in-dom if (elem.offsetParent === null) { return false; @@ -112,7 +104,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { // Determines if a focusable element can be focused at a given point in time function isCurrentlyFocusable(elem) { - if (elem.disabled) { return false; } @@ -143,7 +134,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { var focusableElements = []; for (var i = 0, length = elems.length; i < length; i++) { - var elem = elems[i]; if (excludeClass && elem.classList.contains(excludeClass)) { @@ -163,7 +153,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } function isFocusContainer(elem, direction) { - if (focusableContainerTagNames.indexOf(elem.tagName) !== -1) { return true; } @@ -217,7 +206,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } function getOffset(elem) { - var box; // Support: BlackBerry 5, iOS 3 (original iPhone) @@ -234,7 +222,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } if (box.right === null) { - // Create a new object because some browsers will throw an error when trying to set data onto the Rect object var newBox = { top: box.top, @@ -253,7 +240,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } function nav(activeElement, direction, container, focusableElements) { - activeElement = activeElement || document.activeElement; if (activeElement) { @@ -272,14 +258,10 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { var rect = getOffset(activeElement); // Get elements and work out x/y points - var cache = []; var point1x = parseFloat(rect.left) || 0; var point1y = parseFloat(rect.top) || 0; var point2x = parseFloat(point1x + rect.width - 1) || point1x; var point2y = parseFloat(point1y + rect.height - 1) || point1y; - // Shortcuts to help with compression - var min = Math.min; - var max = Math.max; var sourceMidX = rect.left + (rect.width / 2); var sourceMidY = rect.top + (rect.height / 2); @@ -301,10 +283,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { continue; } - //if (!isCurrentlyFocusableInternal(curr)) { - // continue; - //} - var elementRect = getOffset(curr); // not currently visible @@ -313,7 +291,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } switch (direction) { - case 0: // left if (elementRect.left >= rect.left) { @@ -369,7 +346,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { var distY; switch (direction) { - case 0: // left distX = Math.abs(point1x - Math.min(point1x, x2)); @@ -403,7 +379,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } if (nearestElement) { - // See if there's a focusable container, and if so, send the focus command to that if (activeElement) { var nearestElementFocusableParent = dom.parentWithClass(nearestElement, 'focusable'); @@ -418,12 +393,10 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } function intersectsInternal(a1, a2, b1, b2) { - return (b1 >= a1 && b1 <= a2) || (b2 >= a1 && b2 <= a2); } function intersects(a1, a2, b1, b2) { - return intersectsInternal(a1, a2, b1, b2) || intersectsInternal(b1, b2, a1, a2); } @@ -434,11 +407,9 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } function focusFirst(container, focusableSelector) { - var elems = container.querySelectorAll(focusableSelector); for (var i = 0, length = elems.length; i < length; i++) { - var elem = elems[i]; if (isCurrentlyFocusableInternal(elem)) { @@ -449,11 +420,9 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } function focusLast(container, focusableSelector) { - var elems = [].slice.call(container.querySelectorAll(focusableSelector), 0).reverse(); for (var i = 0, length = elems.length; i < length; i++) { - var elem = elems[i]; if (isCurrentlyFocusableInternal(elem)) { @@ -464,7 +433,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } function moveFocus(sourceElement, container, focusableSelector, offset) { - var elems = container.querySelectorAll(focusableSelector); var list = []; var i; @@ -472,7 +440,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { var elem; for (i = 0, length = elems.length; i < length; i++) { - elem = elems[i]; if (isCurrentlyFocusableInternal(elem)) { @@ -483,7 +450,6 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { var currentIndex = -1; for (i = 0, length = list.length; i < length; i++) { - elem = list[i]; if (sourceElement === elem || elem.contains(sourceElement)) { diff --git a/src/components/guide/guide-settings.js b/src/components/guide/guide-settings.js index 77a3637251..c3ba49f283 100644 --- a/src/components/guide/guide-settings.js +++ b/src/components/guide/guide-settings.js @@ -2,12 +2,10 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio 'use strict'; function saveCategories(context, options) { - var categories = []; var chkCategorys = context.querySelectorAll('.chkCategory'); for (var i = 0, length = chkCategorys.length; i < length; i++) { - var type = chkCategorys[i].getAttribute('data-type'); if (chkCategorys[i].checked) { @@ -25,12 +23,10 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio } function loadCategories(context, options) { - var selectedCategories = options.categories || []; var chkCategorys = context.querySelectorAll('.chkCategory'); for (var i = 0, length = chkCategorys.length; i < length; i++) { - var type = chkCategorys[i].getAttribute('data-type'); chkCategorys[i].checked = !selectedCategories.length || selectedCategories.indexOf(type) !== -1; @@ -38,13 +34,11 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio } function save(context) { - var i; var length; var chkIndicators = context.querySelectorAll('.chkIndicator'); for (i = 0, length = chkIndicators.length; i < length; i++) { - var type = chkIndicators[i].getAttribute('data-type'); userSettings.set('guide-indicator-' + type, chkIndicators[i].checked); } @@ -62,13 +56,11 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio } function load(context) { - var i; var length; var chkIndicators = context.querySelectorAll('.chkIndicator'); for (i = 0, length = chkIndicators.length; i < length; i++) { - var type = chkIndicators[i].getAttribute('data-type'); if (chkIndicators[i].getAttribute('data-default') === 'true') { @@ -90,13 +82,10 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio } function showEditor(options) { - return new Promise(function (resolve, reject) { - var settingsChanged = false; require(['text!./guide-settings.template.html'], function (template) { - var dialogOptions = { removeOnClose: true, scrollY: false @@ -119,12 +108,10 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio dlg.innerHTML = html; dlg.addEventListener('change', function () { - settingsChanged = true; }); dlg.addEventListener('close', function () { - if (layoutManager.tv) { scrollHelper.centerFocus.off(dlg.querySelector('.formDialogContent'), false); } diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index bb4a36497c..bd3ad89aaa 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -2,7 +2,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'use strict'; function showViewSettings(instance) { - require(['guide-settings-dialog'], function (guideSettingsDialog) { guideSettingsDialog.show(instance.categoryOptions).then(function () { instance.refresh(); @@ -11,7 +10,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } function updateProgramCellOnScroll(cell, scrollPct) { - var left = cell.posLeft; if (!left) { left = parseFloat(cell.style.left.replace('%', '')); @@ -43,11 +41,9 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', if (guideProgramName) { if (pctOfWidth > 0 && pctOfWidth <= 100) { - //guideProgramName.style.marginLeft = pctOfWidth + '%'; guideProgramName.style.transform = 'translateX(' + pctOfWidth + '%)'; caret.classList.remove('hide'); } else { - //guideProgramName.style.marginLeft = '0'; guideProgramName.style.transform = 'none'; caret.classList.add('hide'); } @@ -56,7 +52,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', var isUpdatingProgramCellScroll = false; function updateProgramCellsOnScroll(programGrid, programCells) { - if (isUpdatingProgramCellScroll) { return; } @@ -64,13 +59,11 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', isUpdatingProgramCellScroll = true; requestAnimationFrame(function () { - var scrollLeft = programGrid.scrollLeft; var scrollPct = scrollLeft ? (scrollLeft / programGrid.scrollWidth) * 100 : 0; for (var i = 0, length = programCells.length; i < length; i++) { - updateProgramCellOnScroll(programCells[i], scrollPct); } @@ -79,14 +72,12 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } function onProgramGridClick(e) { - if (!layoutManager.tv) { return; } var programCell = dom.parentWithClass(e.target, 'programCell'); if (programCell) { - var startDate = programCell.getAttribute('data-startdate'); var endDate = programCell.getAttribute('data-enddate'); startDate = datetime.parseISO8601Date(startDate, { toLocal: true }).getTime(); @@ -94,7 +85,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', var now = new Date().getTime(); if (now >= startDate && now < endDate) { - var channelId = programCell.getAttribute('data-channelid'); var serverId = programCell.getAttribute('data-serverid'); @@ -110,7 +100,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } function Guide(options) { - var self = this; var items = {}; @@ -121,7 +110,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', var cellCurationMinutes = 30; var cellDurationMs = cellCurationMinutes * 60 * 1000; var msPerDay = 86400000; - var totalRendererdMs = msPerDay; var currentDate; var currentStartIndex = 0; @@ -132,7 +120,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', var programGrid; self.refresh = function () { - currentDate = null; reloadPage(options.element); restartAutoRefresh(); @@ -151,7 +138,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', }; self.destroy = function () { - stopAutoRefresh(); events.off(serverNotifications, 'TimerCreated', onTimerCreated); @@ -165,7 +151,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', }; function restartAutoRefresh() { - stopAutoRefresh(); var intervalMs = 60000 * 15; // (minutes) @@ -183,15 +168,11 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } function normalizeDateToTimeslot(date) { - var minutesOffset = date.getMinutes() - cellCurationMinutes; if (minutesOffset >= 0) { - date.setHours(date.getHours(), cellCurationMinutes, 0, 0); - } else { - date.setHours(date.getHours(), 0, 0, 0); } @@ -207,7 +188,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } function reloadGuide(context, newStartDate, scrollToTimeMs, focusToTimeMs, startTimeOfDayMs, focusProgramOnRender) { - var apiClient = connectionManager.getApiClient(options.serverId); var channelQuery = { @@ -290,12 +270,10 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', }; apiClient.getLiveTvChannels(channelQuery).then(function (channelsResult) { - var btnPreviousPage = context.querySelector('.btnPreviousPage'); var btnNextPage = context.querySelector('.btnNextPage'); if (channelsResult.TotalRecordCount > channelLimit) { - context.querySelector('.guideOptions').classList.remove('hide'); btnPreviousPage.classList.remove('hide'); @@ -312,7 +290,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } else { btnNextPage.disabled = true; } - } else { context.querySelector('.guideOptions').classList.add('hide'); } @@ -343,22 +320,17 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } apiClient.getLiveTvPrograms(programQuery).then(function (programsResult) { - renderGuide(context, date, channelsResult.Items, programsResult.Items, renderOptions, apiClient, scrollToTimeMs, focusToTimeMs, startTimeOfDayMs, focusProgramOnRender); hideLoading(); - }); }); } function getDisplayTime(date) { - if ((typeof date).toString().toLowerCase() === 'string') { try { - date = datetime.parseISO8601Date(date, { toLocal: true }); - } catch (err) { return date; } @@ -368,7 +340,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } function getTimeslotHeadersHtml(startDate, endDateTime) { - var html = ''; // clone @@ -377,7 +348,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', html += '
'; while (startDate.getTime() < endDateTime) { - html += '
'; html += getDisplayTime(startDate); @@ -411,23 +381,19 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } function getTimerIndicator(item) { - var status; if (item.Type === 'SeriesTimer') { return ''; } else if (item.TimerId || item.SeriesTimerId) { - status = item.Status || 'Cancelled'; } else if (item.Type === 'Timer') { - status = item.Status; } else { return ''; } if (item.SeriesTimerId) { - if (status !== 'Cancelled') { return ''; } @@ -439,7 +405,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } function getChannelProgramsHtml(context, date, channel, programs, options, listInfo) { - var html = ''; var startMs = date.getTime(); @@ -463,11 +428,9 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', var now = new Date().getTime(); for (var i = listInfo.startIndex, length = programs.length; i < length; i++) { - var program = programs[i]; if (program.ChannelId !== channel.Id) { - if (programsFound) { break; } @@ -577,7 +540,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', html += '
'; if (program.IsHD && options.showHdIcon) { - //html += ''; if (layoutManager.tv) { html += '
HD
'; } else { @@ -599,11 +561,9 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', } function renderChannelHeaders(context, channels, apiClient) { - var html = ''; for (var i = 0, length = channels.length; i < length; i++) { - var channel = channels[i]; var hasChannelImage = channel.ImageTags.Primary; @@ -615,18 +575,15 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', var title = []; if (channel.ChannelNumber) { - title.push(channel.ChannelNumber); } if (channel.Name) { - title.push(channel.Name); } html += ''; - html += '
'; + html += '
'; + html += '
'; + html += ''; + html += '
'; - html += ''; - html += '
'; - html += ''; + 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..db2bed36a7 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -222,7 +222,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } function setImageUrl(context, state, url) { - currentImgUrl = url; var item = state.NowPlayingItem; var imgContainer = context.querySelector('.nowPlayingPageImageContainer'); @@ -257,7 +256,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } } - var currentImgUrl; return function () { function toggleRepeat() { switch (playbackManager.getRepeatMode()) { @@ -420,7 +418,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var nowPlayingVolumeSliderContainer = context.querySelector('.nowPlayingVolumeSliderContainer'); if (nowPlayingVolumeSlider) { - nowPlayingVolumeSliderContainer.classList.toggle('hide', !showVolumeSlider); if (!nowPlayingVolumeSlider.dragging) { @@ -909,7 +906,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/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index f7026a007e..56327312f6 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -38,7 +38,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 +63,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 +128,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 +182,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f html += '
'; } - } else { html += '

'; } @@ -363,8 +355,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 +535,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f return; } - _osdOpen = true; element.classList.remove('hide'); var onFinish = function () { @@ -578,7 +567,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..37f767524e 100644 --- a/src/components/subtitleeditor/subtitleeditor.js +++ b/src/components/subtitleeditor/subtitleeditor.js @@ -4,45 +4,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', 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 +14,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', url: apiClient.getUrl(url) }).then(function () { - hasChanges = true; require(['toast'], function (toast) { @@ -64,11 +25,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 +36,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', primary: 'delete' }).then(function () { - loading.show(); var itemId = currentItem.Id; @@ -91,34 +49,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 +108,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', itemHtml += ''; return itemHtml; - }).join(''); html += '
'; @@ -170,22 +121,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 +134,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 +145,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 +158,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 +185,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', html += '
'; - //html += ''; - html += '
' + (result.Name) + '
'; html += '
'; if (!layoutManager.tv) { @@ -290,17 +221,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 +233,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 +280,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 +289,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 +308,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', } function showDownloadOptions(button, context, subtitleId) { - var items = []; items.push({ @@ -398,15 +316,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 +329,6 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', break; } }); - }); } @@ -426,12 +340,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 +381,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 +409,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..e825e8e0a2 100644 --- a/src/components/subtitlesync/subtitlesync.js +++ b/src/components/subtitlesync/subtitlesync.js @@ -8,7 +8,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 +140,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..dd04f384aa 100644 --- a/src/components/themeMediaPlayer.js +++ b/src/components/themeMediaPlayer.js @@ -5,13 +5,11 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb 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 +27,6 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb }).then(function () { currentOwnerId = ownerId; }); - } else { stopIfPlaying(); } @@ -44,7 +41,6 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb } function enabled(mediaType) { - if (mediaType === 'Video') { return userSettings.enableThemeVideos(); } @@ -55,7 +51,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 +63,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 +74,6 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playb } document.addEventListener('viewshow', function (e) { - var state = e.detail.state || {}; var item = state.item; @@ -97,15 +89,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/upnextdialog/upnextdialog.js b/src/components/upnextdialog/upnextdialog.js index 3e9c9f9c5e..1dbe71c632 100644 --- a/src/components/upnextdialog/upnextdialog.js +++ b/src/components/upnextdialog/upnextdialog.js @@ -4,7 +4,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l var transitionEndEventName = dom.whichTransitionEvent(); function seriesImageUrl(item, options) { - if (item.Type !== 'Episode') { return null; } @@ -13,9 +12,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 +20,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 +36,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 +55,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 +76,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function getHtml() { - var html = ''; html += '
'; @@ -124,7 +112,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function setNextVideoText() { - var instance = this; var elem = instance.options.parent; @@ -143,7 +130,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function fillItem(item) { - var instance = this; var elem = instance.options.parent; @@ -175,11 +161,9 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function onStartNowClick() { - var options = this.options; if (options) { - var player = options.player; this.hide(); @@ -189,7 +173,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function init(instance, options) { - options.parent.innerHTML = getHtml(); options.parent.classList.add('hide'); @@ -203,7 +186,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function clearHideAnimationEventListeners(instance, elem) { - var fn = instance._onHideAnimationComplete; if (fn) { @@ -214,7 +196,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function onHideAnimationComplete(e) { - var instance = this; var elem = e.target; @@ -225,7 +206,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function hideComingUpNext() { - var instance = this; clearCountdownTextTimeout(this); @@ -259,10 +239,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 +254,6 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } function startComingUpNextHideTimer(instance) { - var timeRemainingMs = getTimeRemainingMs(instance); if (timeRemainingMs <= 0) { @@ -290,14 +267,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 +294,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/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/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/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..2a4fbec37b 100644 --- a/src/controllers/dashboard/dlna/profile.js +++ b/src/controllers/dashboard/dlna/profile.js @@ -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; diff --git a/src/controllers/dashboard/mediaLibrary.js b/src/controllers/dashboard/mediaLibrary.js index b958e69d22..6694a28d0f 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'; @@ -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..5cae08d2fa 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'; diff --git a/src/controllers/dashboard/plugins/add/index.js b/src/controllers/dashboard/plugins/add/index.js index 375a0c0ec7..a3c450dd79 100644 --- a/src/controllers/dashboard/plugins/add/index.js +++ b/src/controllers/dashboard/plugins/add/index.js @@ -66,7 +66,7 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'e } function alertText(options) { - require(['alert'], function (alert) { + require(['alert'], function ({default: alert}) { alert(options); }); } @@ -114,14 +114,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/controllers/dashboard/plugins/available/index.js b/src/controllers/dashboard/plugins/available/index.js index 37df8801b5..1f202d6ff6 100644 --- a/src/controllers/dashboard/plugins/available/index.js +++ b/src/controllers/dashboard/plugins/available/index.js @@ -34,7 +34,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/controllers/dashboard/scheduledtasks/scheduledtask.js b/src/controllers/dashboard/scheduledtasks/scheduledtask.js index fe214fef63..28a21eb630 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) { @@ -99,7 +98,6 @@ import 'emby-select'; } 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/userparentalcontrol.js b/src/controllers/dashboard/users/userparentalcontrol.js index 3fba3fc2b2..e146aac567 100644 --- a/src/controllers/dashboard/users/userparentalcontrol.js +++ b/src/controllers/dashboard/users/userparentalcontrol.js @@ -228,7 +228,6 @@ import 'paper-icon-button-light'; } function showBlockedTagPopup(page) { - import('prompt').then(({default: prompt}) => { prompt({ label: globalize.translate('LabelTag') diff --git a/src/controllers/dashboard/users/userprofilespage.js b/src/controllers/dashboard/users/userprofilespage.js index dbdec4f752..824baef4cf 100644 --- a/src/controllers/dashboard/users/userprofilespage.js +++ b/src/controllers/dashboard/users/userprofilespage.js @@ -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/favorites.js b/src/controllers/favorites.js index 532801bfaf..b649e18d05 100644 --- a/src/controllers/favorites.js +++ b/src/controllers/favorites.js @@ -180,8 +180,7 @@ import 'emby-scroller'; function getItemsHtmlFn(section) { return function (items) { - const supportsImageAnalysis = appHost.supports('imageanalysis'); - let cardLayout = (appHost.preferVisualCards || supportsImageAnalysis) && section.autoCardLayout && section.showTitle; + let cardLayout = appHost.preferVisualCards && section.autoCardLayout && section.showTitle; cardLayout = false; const serverId = this.apiClient.serverId(); const leadingButtons = layoutManager.tv ? [{ diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index 011bc4ac92..e50e2ae092 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -38,7 +38,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function getContextMenuOptions(item, user, button) { - var options = { + return { item: item, open: false, play: false, @@ -53,8 +53,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti user: user, share: true }; - - return options; } function getProgramScheduleHtml(items) { @@ -357,9 +355,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti }); html.push('' + artist.Name + ''); } - html = html.join(' / '); - return html; + return html.join(' / '); } /** @@ -523,6 +520,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 = ''; } @@ -1652,7 +1657,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti html += '

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

    '; - html += ''; html += '
    '; html += '
    '; var shape = 'MusicAlbum' == type.type ? getSquareShape(false) : getPortraitShape(false); @@ -1674,14 +1678,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti var 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) { @@ -1738,7 +1734,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function getVideosHtml(items) { - var html = cardBuilder.getCardsHtml({ + return cardBuilder.getCardsHtml({ items: items, shape: 'autooverflow', showTitle: true, @@ -1747,8 +1743,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti centerText: true, showRuntime: true }); - - return html; } function renderSpecials(page, item, user) { diff --git a/src/controllers/livetv/livetvchannels.js b/src/controllers/livetv/livetvchannels.js index 62906d9d21..3ceda7d476 100644 --- a/src/controllers/livetv/livetvchannels.js +++ b/src/controllers/livetv/livetvchannels.js @@ -1,6 +1,8 @@ define(['cardBuilder', 'imageLoader', 'libraryBrowser', 'loading', 'events', 'userSettings', 'emby-itemscontainer'], function (cardBuilder, imageLoader, libraryBrowser, loading, events, userSettings) { 'use strict'; + 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..d832ca1339 100644 --- a/src/controllers/livetv/livetvrecordings.js +++ b/src/controllers/livetv/livetvrecordings.js @@ -24,7 +24,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..2f451e50fb 100644 --- a/src/controllers/livetv/livetvschedule.js +++ b/src/controllers/livetv/livetvschedule.js @@ -30,17 +30,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..c5d0da60d7 100644 --- a/src/controllers/livetv/livetvseriestimers.js +++ b/src/controllers/livetv/livetvseriestimers.js @@ -3,7 +3,6 @@ define(['datetime', 'cardBuilder', 'imageLoader', 'apphost', 'loading', 'paper-i function renderTimers(context, timers) { var html = ''; - appHost.supports('imageanalysis'); html += cardBuilder.getCardsHtml({ items: timers, shape: 'auto', diff --git a/src/controllers/livetvtuner.js b/src/controllers/livetvtuner.js index 92f705c02f..9250c18432 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 = null != currentId; + 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 = 'hdhomerun' === value; + const supportsTranscoding = 'hdhomerun' === value; + const supportsFavorites = 'hdhomerun' === value; + const supportsTunerIpAddress = 'hdhomerun' === value; + const supportsTunerFileOrUrl = 'm3u' === value; + const supportsStreamLooping = 'm3u' === value; + const supportsTunerCount = 'm3u' === value; + const supportsUserAgent = 'm3u' === value; + const suppportsSubmit = 'other' !== value; + 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..44904633fa 100644 --- a/src/controllers/movies/moviecollections.js +++ b/src/controllers/movies/moviecollections.js @@ -1,6 +1,8 @@ define(['loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, userSettings, globalize) { 'use strict'; + libraryBrowser = libraryBrowser.default || libraryBrowser; + return function (view, params, tabContent) { function getPageData(context) { var key = getSavedQueryKey(context); diff --git a/src/controllers/movies/moviegenres.js b/src/controllers/movies/moviegenres.js index ab410c1bd4..69450989e8 100644 --- a/src/controllers/movies/moviegenres.js +++ b/src/controllers/movies/moviegenres.js @@ -1,6 +1,8 @@ define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader', 'apphost', 'globalize', 'appRouter', 'dom', 'emby-button'], function (layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) { 'use strict'; + libraryBrowser = libraryBrowser.default || libraryBrowser; + return function (view, params, tabContent) { function getPageData() { var key = getSavedQueryKey(); @@ -75,8 +77,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..f4c126c468 100644 --- a/src/controllers/movies/movies.js +++ b/src/controllers/movies/movies.js @@ -1,6 +1,8 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser', 'alphaPicker', 'listView', 'cardBuilder', 'globalize', 'emby-itemscontainer'], function (loading, layoutManager, userSettings, events, libraryBrowser, AlphaPicker, listView, cardBuilder, globalize) { 'use strict'; + 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..4ffe7888cf 100644 --- a/src/controllers/movies/moviesrecommended.js +++ b/src/controllers/movies/moviesrecommended.js @@ -346,8 +346,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 +368,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 +385,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..84d7c538ee 100644 --- a/src/controllers/movies/movietrailers.js +++ b/src/controllers/movies/movietrailers.js @@ -1,6 +1,8 @@ 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'; + 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..bc6d2c4e37 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,8 +70,8 @@ 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) { itemsContainer.classList.add('vertical-list'); @@ -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..985c629103 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,8 +54,8 @@ 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) { itemsContainer.classList.add('vertical-list'); @@ -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..82041c5a56 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) { 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/controllers/playback/video/index.html b/src/controllers/playback/video/index.html index 452c8a9af8..cf3d0beff8 100644 --- a/src/controllers/playback/video/index.html +++ b/src/controllers/playback/video/index.html @@ -28,7 +28,7 @@ - @@ -44,7 +44,7 @@ - diff --git a/src/controllers/playback/video/index.js b/src/controllers/playback/video/index.js index e821c2393e..5a22ebf285 100644 --- a/src/controllers/playback/video/index.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'; @@ -367,6 +368,7 @@ import 'css!assets/css/videoosd'; function hideOsd() { slideUpToHide(headerElement); hideMainOsdControls(); + mouseManager.hideCursor(); } function toggleOsd() { @@ -435,6 +437,7 @@ import 'css!assets/css/videoosd'; const elem = osdBottomElement; clearHideAnimationEventListeners(elem); elem.classList.add('videoOsdBottom-hidden'); + dom.addEventListener(elem, transitionEndEventName, onHideAnimationComplete, { once: true }); @@ -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); @@ -1132,6 +1134,7 @@ import 'css!assets/css/videoosd'; clickedElement = e.target; const key = keyboardnavigation.getKeyName(e); + const isKeyModified = e.ctrlKey || e.altKey; if (!currentVisibleMenu && 32 === e.keyCode) { playbackManager.playPause(currentPlayer); @@ -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/controllers/session/addServer/index.js b/src/controllers/session/addServer/index.js index 1129283246..7d3ba7f471 100644 --- a/src/controllers/session/addServer/index.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/controllers/session/selectServer/index.js b/src/controllers/session/selectServer/index.js index 3e36b74859..b7d7b9d221 100644 --- a/src/controllers/session/selectServer/index.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/tvgenres.js b/src/controllers/shows/tvgenres.js index d686a62197..87d3a2e240 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 */ @@ -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..1ee70c8f88 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'; 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/controllers/user/home/index.js b/src/controllers/user/home/index.js index e7058fd3ac..f811aa52b9 100644 --- a/src/controllers/user/home/index.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/controllers/user/menu/index.js b/src/controllers/user/menu/index.js index ef4b3b21c8..f44a193a52 100644 --- a/src/controllers/user/menu/index.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/controllers/user/playback/index.js b/src/controllers/user/playback/index.js index 5bcf055cd3..16c50a1980 100644 --- a/src/controllers/user/playback/index.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/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..a135079a7d 100644 --- a/src/index.html +++ b/src/index.html @@ -129,7 +129,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 +139,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/scroller.js b/src/libraries/scroller.js index 8c67127eb3..645a8ea85c 100644 --- a/src/libraries/scroller.js +++ b/src/libraries/scroller.js @@ -872,13 +872,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/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/chromecastPlayer/chromecastHelpers.js b/src/plugins/chromecastPlayer/chromecastHelpers.js index ca2d27c977..3fbff5507b 100644 --- a/src/plugins/chromecastPlayer/chromecastHelpers.js +++ b/src/plugins/chromecastPlayer/chromecastHelpers.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..d3fc8d0ef8 100644 --- a/src/plugins/chromecastPlayer/plugin.js +++ b/src/plugins/chromecastPlayer/plugin.js @@ -8,7 +8,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' var PlayerName = 'Google Cast'; function sendConnectionResult(isOk) { - var resolve = currentResolve; var reject = currentReject; @@ -60,7 +59,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' var messageNamespace = 'urn:x-cast:com.connectsdk'; var CastPlayer = function () { - /* device variables */ // @type {DEVICE_STATE} A state for device this.deviceState = DEVICE_STATE.IDLE; @@ -325,7 +323,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; CastPlayer.prototype.sendMessage = function (message) { - var player = this; var receiverName = null; @@ -391,7 +388,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 +449,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 +469,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' } function getItemsForPlayback(apiClient, query) { - var userId = apiClient.getCurrentUserId(); if (query.Ids && query.Ids.split(',').length === 1) { @@ -486,7 +479,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; }); } else { - query.Limit = query.Limit || 100; query.ExcludeLocationTypes = 'Virtual'; query.EnableTotalRecordCount = false; @@ -496,9 +488,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 +497,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' } function initializeChromecast() { - var instance = this; instance._castPlayer = new CastPlayer(); @@ -519,7 +508,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' })); events.on(instance._castPlayer, 'connect', function (e) { - if (currentResolve) { sendConnectionResult(true); } else { @@ -532,7 +520,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }); events.on(instance._castPlayer, 'playbackstart', function (e, data) { - console.debug('cc: playbackstart'); instance._castPlayer.initializeCastPlayer(); @@ -542,7 +529,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 +546,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 +560,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 +568,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' } function ChromecastPlayer() { - // playbackManager needs this this.name = PlayerName; this.type = 'mediaplayer'; @@ -624,7 +607,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 +643,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.getPlayerStateInternal = function (data) { - var triggerStateChange = false; if (data && !this.lastPlayerData) { triggerStateChange = true; @@ -682,13 +663,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 +684,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.seek = function (position) { - position = parseInt(position); position = position / 10000000; @@ -737,7 +715,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.setMaxStreamingBitrate = function (options) { - this._castPlayer.sendMessage({ options: options, command: 'SetMaxStreamingBitrate' @@ -773,11 +750,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 +774,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 +810,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.displayContent = function (options) { - this._castPlayer.sendMessage({ options: options, command: 'DisplayContent' @@ -844,7 +817,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.setMute = function (isMuted) { - var castPlayer = this._castPlayer; if (isMuted) { @@ -873,7 +845,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.playTrailers = function (item) { - this._castPlayer.sendMessage({ options: { ItemId: item.Id, @@ -902,7 +873,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.toggleMute = function () { - this._castPlayer.sendMessage({ options: {}, command: 'ToggleMute' @@ -946,7 +916,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.getVolume = function () { - var state = this.lastPlayerData || {}; state = state.PlayState || {}; @@ -971,7 +940,6 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.currentTime = function (val) { - if (val != null) { return this.seek(val); } @@ -1008,45 +976,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 +1023,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 +1038,8 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' Ids: options.ids.join(',') }).then(function (result) { - options.items = result.Items; return instance.playWithCommand(options, 'PlayNow'); - }); } }; @@ -1119,7 +1072,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..083a61670f 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 `