diff --git a/.ci/azure-pipelines-package.yml b/.ci/azure-pipelines-package.yml index 2249bd20eb..bf4234ec97 100644 --- a/.ci/azure-pipelines-package.yml +++ b/.ci/azure-pipelines-package.yml @@ -36,6 +36,14 @@ jobs: targetPath: '$(Build.SourcesDirectory)/deployment/dist' artifactName: 'jellyfin-web-$(BuildConfiguration)' + - task: SSH@0 + displayName: 'Create target directory on repository server' + condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) + inputs: + sshEndpoint: repository + runOptions: 'inline' + inline: 'mkdir -p /srv/repository/incoming/azure/$(Build.BuildNumber)/$(BuildConfiguration)' + - task: CopyFilesOverSSH@0 displayName: 'Upload artifacts to repository server' condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) diff --git a/package.json b/package.json index ab47eb5389..205a687800 100644 --- a/package.json +++ b/package.json @@ -5,16 +5,16 @@ "repository": "https://github.com/jellyfin/jellyfin-web", "license": "GPL-2.0-or-later", "devDependencies": { - "@babel/core": "^7.10.3", + "@babel/core": "^7.10.5", "@babel/plugin-proposal-class-properties": "^7.10.1", "@babel/plugin-proposal-private-methods": "^7.10.1", - "@babel/plugin-transform-modules-amd": "^7.9.6", + "@babel/plugin-transform-modules-amd": "^7.10.5", "@babel/polyfill": "^7.8.7", "@babel/preset-env": "^7.10.3", - "autoprefixer": "^9.8.2", + "autoprefixer": "^9.8.5", "babel-eslint": "^11.0.0-beta.2", "babel-loader": "^8.0.6", - "browser-sync": "^2.26.7", + "browser-sync": "^2.26.10", "copy-webpack-plugin": "^5.1.1", "css-loader": "^3.6.0", "cssnano": "^4.1.10", @@ -57,15 +57,15 @@ "blurhash": "^1.1.3", "classlist.js": "https://github.com/eligrey/classList.js/archive/1.2.20180112.tar.gz", "core-js": "^3.6.5", - "date-fns": "^2.14.0", + "date-fns": "^2.15.0", "epubjs": "^0.3.85", "fast-text-encoding": "^1.0.3", "flv.js": "^1.5.0", "headroom.js": "^0.11.0", - "hls.js": "^0.14.0", + "hls.js": "^0.14.3", "howler": "^2.2.0", "intersection-observer": "^0.11.0", - "jellyfin-apiclient": "^1.3.0", + "jellyfin-apiclient": "^1.4.1", "jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto", "jquery": "^3.5.1", "jstree": "^3.3.10", @@ -80,7 +80,7 @@ "sortablejs": "^1.10.2", "swiper": "^5.4.5", "webcomponents.js": "^0.7.24", - "whatwg-fetch": "^3.0.0" + "whatwg-fetch": "^3.2.0" }, "babel": { "presets": [ @@ -116,6 +116,12 @@ "src/components/syncPlay/timeSyncManager.js", "src/controllers/dashboard/logs.js", "src/controllers/dashboard/plugins/repositories.js", + "src/controllers/playback/nowplaying.js", + "src/controllers/playback/videoosd.js", + "src/controllers/user/display.js", + "src/controllers/user/home.js", + "src/controllers/user/playback.js", + "src/controllers/user/subtitles.js", "src/plugins/bookPlayer/plugin.js", "src/plugins/bookPlayer/tableOfContents.js", "src/plugins/photoPlayer/plugin.js", diff --git a/src/assets/css/dashboard.css b/src/assets/css/dashboard.css index 894d7332f4..48e6fe807e 100644 --- a/src/assets/css/dashboard.css +++ b/src/assets/css/dashboard.css @@ -235,6 +235,15 @@ div[data-role=controlgroup] a.ui-btn-active { width: 50%; } +.localUsers .cardText-secondary { + white-space: pre-wrap; + height: 3em; +} + +.customCssContainer textarea { + resize: none; +} + @media all and (min-width: 70em) { .dashboardSections { -webkit-flex-wrap: wrap; diff --git a/src/assets/css/ios.css b/src/assets/css/ios.css index 57de0c5fdd..2b61f49a4e 100644 --- a/src/assets/css/ios.css +++ b/src/assets/css/ios.css @@ -1,8 +1,3 @@ html { font-size: 82% !important; } - -.formDialogFooter { - position: static !important; - margin: 0 -1em !important; -} diff --git a/src/assets/css/librarybrowser.css b/src/assets/css/librarybrowser.css index 460585ae61..61815a590f 100644 --- a/src/assets/css/librarybrowser.css +++ b/src/assets/css/librarybrowser.css @@ -175,6 +175,10 @@ width: 100%; } +.layout-tv .sectionTabs { + width: 55%; +} + .selectedMediaFolder { background-color: #f2f2f2 !important; } @@ -269,7 +273,7 @@ } } -@media all and (max-width: 84em) { +@media all and (max-width: 100em) { .withSectionTabs .headerTop { padding-bottom: 0.55em; } @@ -277,9 +281,13 @@ .sectionTabs { font-size: 83.5%; } + + .layout-tv .sectionTabs { + width: 100%; + } } -@media all and (min-width: 84em) { +@media all and (min-width: 100em) { .headerTop { padding: 0.8em 0.8em; } @@ -910,21 +918,7 @@ div.itemDetailGalleryLink.defaultCardBackground { } } -@media all and (min-width: 62.5em) { - .headerTop { - padding-left: 0.8em; - padding-right: 0.8em; - } - - .headerTabs { - align-self: center; - width: auto; - align-items: center; - justify-content: center; - margin-top: -4.2em; - position: relative; - } - +@media all and (min-width: 100em) { .detailFloatingButton { display: none !important; } diff --git a/src/assets/css/scrollstyles.css b/src/assets/css/scrollstyles.css index 1cb3207e06..67c6202252 100644 --- a/src/assets/css/scrollstyles.css +++ b/src/assets/css/scrollstyles.css @@ -12,6 +12,7 @@ .hiddenScrollX, .layout-tv .scrollX { -ms-overflow-style: none; + scrollbar-width: none; } .hiddenScrollX-forced { @@ -40,6 +41,7 @@ .hiddenScrollY, .layout-tv .smoothScrollY { -ms-overflow-style: none; + scrollbar-width: none; /* Can't do this because it not only hides the scrollbar, but also prevents scrolling */ diff --git a/src/assets/css/site.css b/src/assets/css/site.css index 1a8873ba97..f6326f4c9e 100644 --- a/src/assets/css/site.css +++ b/src/assets/css/site.css @@ -129,3 +129,7 @@ div[data-role=page] { .hide-scroll { overflow-y: hidden; } + +.w-100 { + width: 100%; +} diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 0861cf7e00..58c64e7d43 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -222,46 +222,13 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } function normalizeImageOptions(options) { - var scaleFactor = browser.tv ? 0.8 : 1; - var setQuality; - if (options.maxWidth) { - options.maxWidth = Math.round(options.maxWidth * scaleFactor); + if (options.maxWidth || options.width || options.maxHeight || options.height) { setQuality = true; } - if (options.width) { - options.width = Math.round(options.width * scaleFactor); - setQuality = true; - } - - if (options.maxHeight) { - options.maxHeight = Math.round(options.maxHeight * scaleFactor); - setQuality = true; - } - - if (options.height) { - options.height = Math.round(options.height * scaleFactor); - setQuality = true; - } - - if (setQuality) { - var quality; - var type = options.type || 'Primary'; - - if (browser.tv || browser.slow) { - // TODO: wtf - if (browser.chrome) { - // webp support - quality = type === 'Primary' ? 40 : 50; - } else { - quality = type === 'Backdrop' ? 60 : 50; - } - } else { - quality = type === 'Backdrop' ? 70 : 90; - } - - options.quality = quality; + if (setQuality && !options.quality) { + options.quality = 90; } } diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index e906e806ec..d192bed7f0 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -1468,7 +1468,7 @@ import 'programStyles'; let additionalCardContent = ''; - if (layoutManager.desktop) { + if (layoutManager.desktop && !options.disableHoverMenu) { additionalCardContent += getHoverMenuHtml(item, action, options); } @@ -1497,12 +1497,12 @@ import 'programStyles'; const userData = item.UserData || {}; - if (itemHelper.canMarkPlayed(item) && !options.disableHoverMenu) { + if (itemHelper.canMarkPlayed(item)) { require(['emby-playstatebutton']); html += ''; } - if (itemHelper.canRate(item) && !options.disableHoverMenu) { + if (itemHelper.canRate(item)) { const likes = userData.Likes == null ? '' : userData.Likes; @@ -1510,10 +1510,7 @@ import 'programStyles'; html += ''; } - if (!options.disableHoverMenu) { - html += ''; - } - + html += ''; html += ''; html += ''; diff --git a/src/components/listview/listview.js b/src/components/listview/listview.js index dda0d34903..60340e2a0e 100644 --- a/src/components/listview/listview.js +++ b/src/components/listview/listview.js @@ -273,7 +273,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan imageClass += ' itemAction'; } - var imageAction = playOnImageClick ? 'resume' : action; + var imageAction = playOnImageClick ? 'link' : action; if (imgUrl) { html += '
'; diff --git a/src/components/loading/loader.gif b/src/components/loading/loader.gif deleted file mode 100644 index 86fb6daa79..0000000000 Binary files a/src/components/loading/loader.gif and /dev/null differ diff --git a/src/components/loading/loading.js b/src/components/loading/loading.js index 9a9aa3ca7d..f36e41f44d 100644 --- a/src/components/loading/loading.js +++ b/src/components/loading/loading.js @@ -1,10 +1,6 @@ -define(['components/loading/loadingLegacy', 'browser', 'css!./loading'], function (loadingLegacy, browser) { +define(['css!./loading'], function () { 'use strict'; - if (browser.tizen || browser.operaTv || browser.chromecast || browser.orsay || browser.web0s || browser.ps4) { - return loadingLegacy; - } - var loadingElem; var layer1; var layer2; diff --git a/src/components/loading/loadingLegacy.css b/src/components/loading/loadingLegacy.css deleted file mode 100644 index 17ea94950e..0000000000 --- a/src/components/loading/loadingLegacy.css +++ /dev/null @@ -1,10 +0,0 @@ -.loading-spinner { - margin-top: -3em; - margin-left: -3em; - width: 6em; - height: 6em; - position: fixed; - top: 50%; - left: 50%; - z-index: 9999999; -} diff --git a/src/components/loading/loadingLegacy.js b/src/components/loading/loadingLegacy.js deleted file mode 100644 index d766a4aca4..0000000000 --- a/src/components/loading/loadingLegacy.js +++ /dev/null @@ -1,28 +0,0 @@ -define(['require', 'css!./loadingLegacy'], function (require) { - 'use strict'; - - var loadingElem; - - return { - show: function () { - var elem = loadingElem; - if (!elem) { - elem = document.createElement('img'); - elem.src = require.toUrl('.').split('?')[0] + '/loader.gif'; - - loadingElem = elem; - elem.classList.add('loading-spinner'); - - document.body.appendChild(elem); - } - - elem.classList.remove('hide'); - }, - hide: function () { - var elem = loadingElem; - if (elem) { - elem.classList.add('hide'); - } - } - }; -}); diff --git a/src/components/metadataEditor/metadataEditor.js b/src/components/metadataEditor/metadataEditor.js index 61a4ba7f24..3674bf2720 100644 --- a/src/components/metadataEditor/metadataEditor.js +++ b/src/components/metadataEditor/metadataEditor.js @@ -245,6 +245,43 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi }); } + function afterDeleted(context, item) { + var parentId = item.ParentId || item.SeasonId || item.SeriesId; + + if (parentId) { + reload(context, parentId, item.ServerId); + } else { + require(['appRouter'], function (appRouter) { + appRouter.goHome(); + }); + } + } + + function showMoreMenu(context, button, user) { + require(['itemContextMenu'], function (itemContextMenu) { + var item = currentItem; + + itemContextMenu.show({ + item: item, + positionTo: button, + edit: false, + editImages: true, + editSubtitles: true, + sync: false, + share: false, + play: false, + queue: false, + user: user + }).then(function (result) { + if (result.deleted) { + afterDeleted(context, item); + } else if (result.updated) { + reload(context, item.Id, item.ServerId); + } + }); + }); + } + function onEditorClick(e) { var btnRemoveFromEditorList = dom.parentWithClass(e.target, 'btnRemoveFromEditorList'); @@ -270,7 +307,6 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi } function init(context, apiClient) { - context.querySelector('.externalIds').addEventListener('click', function (e) { var btnOpenExternalId = dom.parentWithClass(e.target, 'btnOpenExternalId'); if (btnOpenExternalId) { @@ -294,13 +330,17 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi closeDialog(false); }); - context.querySelector('.btnHeaderSave').addEventListener('click', function (e) { + context.querySelector('.btnMore').addEventListener('click', function (e) { + getApiClient().getCurrentUser().then(function (user) { + showMoreMenu(context, e.target, user); + }); + }); + context.querySelector('.btnHeaderSave').addEventListener('click', function (e) { context.querySelector('.btnSave').click(); }); context.querySelector('#chkLockData').addEventListener('click', function (e) { - if (!e.target.checked) { showElement('.providerSettingsContainer'); } else { @@ -1088,6 +1128,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi elem.innerHTML = globalize.translateDocument(template, 'core'); elem.querySelector('.formDialogFooter').classList.remove('formDialogFooter'); + elem.querySelector('.btnClose').classList.add('hide'); elem.querySelector('.btnHeaderSave').classList.remove('hide'); elem.querySelector('.btnCancel').classList.add('hide'); diff --git a/src/components/metadataEditor/metadataEditor.template.html b/src/components/metadataEditor/metadataEditor.template.html index 4b4e2cf965..aad3557bad 100644 --- a/src/components/metadataEditor/metadataEditor.template.html +++ b/src/components/metadataEditor/metadataEditor.template.html @@ -8,6 +8,9 @@ ${Save} + diff --git a/src/components/nowPlayingBar/nowPlayingBar.css b/src/components/nowPlayingBar/nowPlayingBar.css index e545d82d1e..a884f65769 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.css +++ b/src/components/nowPlayingBar/nowPlayingBar.css @@ -114,8 +114,6 @@ .nowPlayingBarUserDataButtons { display: inline-block; - margin-left: 1em; - margin-right: 1em; } .nowPlayingBarPositionSlider::-webkit-slider-thumb { diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index a229fab4ba..95c4372f25 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -72,7 +72,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', if (layoutManager.mobile) { html += ''; } else { - html += ''; + html += ''; } html += '
'; @@ -204,15 +204,11 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', volumeSliderContainer.classList.toggle('hide', appHost.supports('physicalvolumecontrol')); - function setVolume() { + volumeSlider.addEventListener('input', (e) => { if (currentPlayer) { - currentPlayer.setVolume(this.value); + currentPlayer.setVolume(e.target.value); } - } - - volumeSlider.addEventListener('change', setVolume); - volumeSlider.addEventListener('mousemove', setVolume); - volumeSlider.addEventListener('touchmove', setVolume); + }); positionSlider.addEventListener('change', function () { @@ -355,7 +351,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', function updateRepeatModeDisplay(repeatMode) { toggleRepeatButtonIcon.classList.remove('repeat', 'repeat_one'); - const cssClass = 'repeatButton-active'; + const cssClass = 'buttonActive'; switch (repeatMode) { case 'RepeatAll': @@ -375,18 +371,14 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } function updateTimeDisplay(positionTicks, runtimeTicks, bufferedRanges) { - // See bindEvents for why this is necessary if (positionSlider && !positionSlider.dragging) { if (runtimeTicks) { - var pct = positionTicks / runtimeTicks; pct *= 100; positionSlider.value = pct; - } else { - positionSlider.value = 0; } } @@ -396,9 +388,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } if (currentTimeElement) { - var timeText = positionTicks == null ? '--:--' : datetime.getDisplayRunningTime(positionTicks); - if (runtimeTicks) { timeText += ' / ' + datetime.getDisplayRunningTime(runtimeTicks); } @@ -606,14 +596,11 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', function onPlaybackStart(e, state) { console.debug('nowplaying event: ' + e.type); - var player = this; - onStateChanged.call(player, e, state); } function onRepeatModeChange() { - if (!isEnabled) { return; } @@ -628,9 +615,8 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', let shuffleMode = playbackManager.getQueueShuffleMode(); let context = nowPlayingBarElement; - const cssClass = 'shuffleQueue-active'; + const cssClass = 'buttonActive'; let toggleShuffleButton = context.querySelector('.btnShuffleQueue'); - switch (shuffleMode) { case 'Shuffle': toggleShuffleButton.classList.add(cssClass); @@ -643,7 +629,6 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } function showNowPlayingBar() { - if (!isVisibilityAllowed) { hideNowPlayingBar(); return; diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 797fc39bd2..cb1a91fb75 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -72,7 +72,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla const now = (new Date).getTime(); if (method !== reportPlaybackLastMethod || now - (reportPlaybackLastTime || 0) >= reportPlaybackLogDelay) { - console.debug(method + '-' + JSON.stringify(info)); reportPlaybackLastMethod = method; reportPlaybackLastTime = now; } diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index d4511a9dd7..c260799585 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -278,6 +278,10 @@ flex-direction: column; } + .layout-desktop .nowPlayingPageUserDataButtons { + display: none; + } + .nowPlayingInfoContainer { -webkit-box-orient: vertical !important; -webkit-box-direction: normal !important; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 33c44ab400..949276337f 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -359,7 +359,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function updateRepeatModeDisplay(repeatMode) { var context = dlg; let toggleRepeatButtons = context.querySelectorAll('.repeatToggleButton'); - const cssClass = 'repeatButton-active'; + const cssClass = 'buttonActive'; let innHtml = ''; let repeatOn = true; @@ -494,7 +494,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL itemsContainer.innerHTML = html; if (focusedItemPlaylistId !== null) { focusedItemPlaylistId = focusedItemPlaylistId.getAttribute('data-playlistitemid'); - const newFocusedItem = itemsContainer.querySelector(`button[data-playlistitemid=${focusedItemPlaylistId}]`); + const newFocusedItem = itemsContainer.querySelector(`button[data-playlistitemid="${focusedItemPlaylistId}"]`); if (newFocusedItem !== null) { newFocusedItem.focus(); } @@ -503,7 +503,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var playlistItemId = playbackManager.getCurrentPlaylistItemId(player); if (playlistItemId) { - var img = itemsContainer.querySelector('.listItem[data-playlistItemId="' + playlistItemId + '"] .listItemImage'); + var img = itemsContainer.querySelector(`.listItem[data-playlistItemId="${playlistItemId}"] .listItemImage`); if (img) { img.classList.remove('lazy'); @@ -528,7 +528,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function onShuffleQueueModeChange(updateView = true) { let shuffleMode = playbackManager.getQueueShuffleMode(this); let context = dlg; - const cssClass = 'shuffleQueue-active'; + const cssClass = 'buttonActive'; let shuffleButtons = context.querySelectorAll('.btnShuffleQueue'); for (let shuffleButton of shuffleButtons) { @@ -788,13 +788,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL return datetime.getDisplayRunningTime(ticks); }; - function setVolume() { - playbackManager.setVolume(this.value, currentPlayer); - } + context.querySelector('.nowPlayingVolumeSlider').addEventListener('input', (e) => { + playbackManager.setVolume(e.target.value, currentPlayer); + }); - context.querySelector('.nowPlayingVolumeSlider').addEventListener('change', setVolume); - context.querySelector('.nowPlayingVolumeSlider').addEventListener('mousemove', setVolume); - context.querySelector('.nowPlayingVolumeSlider').addEventListener('touchmove', setVolume); context.querySelector('.buttonMute').addEventListener('click', function () { playbackManager.toggleMute(currentPlayer); }); diff --git a/src/components/search/searchresults.js b/src/components/search/searchresults.js index d4de2349a4..88c68fdedd 100644 --- a/src/components/search/searchresults.js +++ b/src/components/search/searchresults.js @@ -464,7 +464,7 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', showTitle: true, overlayText: false, centerText: true, - action: 'play' + overlayPlayButton: true }); diff --git a/src/components/syncPlay/groupSelectionMenu.js b/src/components/syncPlay/groupSelectionMenu.js index 48b22261f4..360aa0b0c2 100644 --- a/src/components/syncPlay/groupSelectionMenu.js +++ b/src/components/syncPlay/groupSelectionMenu.js @@ -37,7 +37,7 @@ function showNewJoinGroupSelection (button, user, apiClient) { console.debug('No item is currently playing.'); } - apiClient.sendSyncPlayCommand('ListGroups').then(function (response) { + apiClient.getSyncPlayGroups().then(function (response) { response.json().then(function (groups) { var menuItems = groups.map(function (group) { return { @@ -83,9 +83,9 @@ function showNewJoinGroupSelection (button, user, apiClient) { actionsheet.show(menuOptions).then(function (id) { if (id == 'new-group') { - apiClient.sendSyncPlayCommand('NewGroup'); - } else { - apiClient.sendSyncPlayCommand('JoinGroup', { + apiClient.createSyncPlayGroup(); + } else if (id) { + apiClient.joinSyncPlayGroup({ GroupId: id, PlayingItemId: playingItemId }); @@ -140,7 +140,7 @@ function showLeaveGroupSelection (button, user, apiClient) { actionsheet.show(menuOptions).then(function (id) { if (id == 'leave-group') { - apiClient.sendSyncPlayCommand('LeaveGroup'); + apiClient.leaveSyncPlayGroup(); } }).catch((error) => { console.error('SyncPlay: unexpected error showing group menu:', error); diff --git a/src/components/syncPlay/syncPlayManager.js b/src/components/syncPlay/syncPlayManager.js index 860e3edcd4..c8660b2bc4 100644 --- a/src/components/syncPlay/syncPlayManager.js +++ b/src/components/syncPlay/syncPlayManager.js @@ -139,7 +139,7 @@ class SyncPlayManager { return; } - apiClient.sendSyncPlayCommand('UpdatePing', { + apiClient.sendSyncPlayPing({ Ping: ping }); } @@ -212,6 +212,7 @@ class SyncPlayManager { if (!this.lastPlaybackWaiting) { this.lastPlaybackWaiting = new Date(); } + events.trigger(this, 'waiting'); } @@ -288,6 +289,7 @@ class SyncPlayManager { player.setPlaybackRate(this.localPlayerPlaybackRate); this.localPlayerPlaybackRate = 1.0; } + this.currentPlayer = null; this.playbackRateSupported = false; } @@ -433,6 +435,7 @@ class SyncPlayManager { }); return; } + // Get playing item id let playingItemId; try { @@ -447,7 +450,7 @@ class SyncPlayManager { if (!success) { console.warning('Error reporting playback state to server. Joining group will fail.'); } - apiClient.sendSyncPlayCommand('JoinGroup', { + apiClient.joinSyncPlayGroup({ GroupId: groupId, PlayingItemId: playingItemId }); @@ -619,6 +622,7 @@ class SyncPlayManager { if (this.currentPlayer) { this.currentPlayer.setPlaybackRate(1); } + this.clearSyncIcon(); } @@ -658,7 +662,7 @@ class SyncPlayManager { */ playRequest (player) { var apiClient = connectionManager.currentApiClient(); - apiClient.sendSyncPlayCommand('PlayRequest'); + apiClient.requestSyncPlayStart(); } /** @@ -666,7 +670,7 @@ class SyncPlayManager { */ pauseRequest (player) { var apiClient = connectionManager.currentApiClient(); - apiClient.sendSyncPlayCommand('PauseRequest'); + apiClient.requestSyncPlayPause(); // Pause locally as well, to give the user some little control playbackManager._localUnpause(player); } @@ -676,7 +680,7 @@ class SyncPlayManager { */ seekRequest (PositionTicks, player) { var apiClient = connectionManager.currentApiClient(); - apiClient.sendSyncPlayCommand('SeekRequest', { + apiClient.requestSyncPlaySeek({ PositionTicks: PositionTicks }); } diff --git a/src/controllers/auth/login.js b/src/controllers/auth/login.js index c0c37e27d6..db468fd6f4 100644 --- a/src/controllers/auth/login.js +++ b/src/controllers/auth/login.js @@ -1,4 +1,4 @@ -define(['apphost', 'appSettings', 'dom', 'connectionManager', 'loading', 'layoutManager', 'browser', 'globalize', 'cardStyle', 'emby-checkbox'], function (appHost, appSettings, dom, connectionManager, loading, layoutManager, browser, globalize) { +define(['apphost', 'appSettings', 'dom', 'connectionManager', 'loading', 'layoutManager', 'libraryMenu', 'browser', 'globalize', 'cardStyle', 'emby-checkbox'], function (appHost, appSettings, dom, connectionManager, loading, layoutManager, libraryMenu, browser, globalize) { 'use strict'; var enableFocusTransform = !browser.slow && !browser.edge; @@ -7,18 +7,10 @@ define(['apphost', 'appSettings', 'dom', 'connectionManager', 'loading', 'layout loading.show(); apiClient.authenticateUserByName(username, password).then(function (result) { var user = result.User; - var serverId = getParameterByName('serverid'); - var newUrl; - - if (user.Policy.IsAdministrator && !serverId) { - newUrl = 'dashboard.html'; - } else { - newUrl = 'home.html'; - } - loading.hide(); + Dashboard.onServerChanged(user.Id, result.AccessToken, apiClient); - Dashboard.navigate(newUrl); + Dashboard.navigate('home.html'); }, function (response) { page.querySelector('#txtManualName').value = ''; page.querySelector('#txtManualPassword').value = ''; @@ -194,6 +186,7 @@ define(['apphost', 'appSettings', 'dom', 'connectionManager', 'loading', 'layout }); view.addEventListener('viewshow', function (e) { loading.show(); + libraryMenu.setTransparentMenu(true); if (!appHost.supports('multiserver')) { view.querySelector('.btnSelectServer').classList.add('hide'); @@ -215,5 +208,8 @@ define(['apphost', 'appSettings', 'dom', 'connectionManager', 'loading', 'layout view.querySelector('.disclaimer').textContent = options.LoginDisclaimer || ''; }); }); + view.addEventListener('viewhide', function (e) { + libraryMenu.setTransparentMenu(false); + }); }; }); diff --git a/src/controllers/auth/selectserver.js b/src/controllers/auth/selectserver.js index ba88313484..20c014ce0d 100644 --- a/src/controllers/auth/selectserver.js +++ b/src/controllers/auth/selectserver.js @@ -1,4 +1,4 @@ -define(['loading', 'appRouter', 'layoutManager', 'appSettings', 'apphost', 'focusManager', 'connectionManager', 'globalize', 'actionsheet', 'dom', 'browser', 'material-icons', 'flexStyles', 'emby-scroller', 'emby-itemscontainer', 'cardStyle', 'emby-button'], function (loading, appRouter, layoutManager, appSettings, appHost, focusManager, connectionManager, globalize, actionSheet, dom, browser) { +define(['loading', 'appRouter', 'layoutManager', 'libraryMenu', 'appSettings', 'apphost', 'focusManager', 'connectionManager', 'globalize', 'actionsheet', 'dom', 'browser', 'material-icons', 'flexStyles', 'emby-scroller', 'emby-itemscontainer', 'cardStyle', 'emby-button'], function (loading, appRouter, layoutManager, libraryMenu, appSettings, appHost, focusManager, connectionManager, globalize, actionSheet, dom, browser) { 'use strict'; var enableFocusTransform = !browser.slow && !browser.edge; @@ -183,6 +183,7 @@ define(['loading', 'appRouter', 'layoutManager', 'appSettings', 'apphost', 'focu view.addEventListener('viewshow', function (e) { var isRestored = e.detail.isRestored; appRouter.setTitle(null); + libraryMenu.setTransparentMenu(true); if (!isRestored) { loadServers(); diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index 6a378903d3..e6e01338b0 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -169,13 +169,7 @@ define(['datetime', 'events', 'itemHelper', 'serverNotifications', 'dom', 'globa function reloadSystemInfo(view, apiClient) { apiClient.getSystemInfo().then(function (systemInfo) { view.querySelector('#serverName').innerHTML = globalize.translate('DashboardServerName', systemInfo.ServerName); - var localizedVersion = globalize.translate('DashboardVersionNumber', systemInfo.Version); - - if (systemInfo.SystemUpdateLevel !== 'Release') { - localizedVersion += ' ' + systemInfo.SystemUpdateLevel; - } - - view.querySelector('#versionNumber').innerHTML = localizedVersion; + view.querySelector('#versionNumber').innerHTML = globalize.translate('DashboardVersionNumber', systemInfo.Version); view.querySelector('#operatingSystem').innerHTML = globalize.translate('DashboardOperatingSystem', systemInfo.OperatingSystem); view.querySelector('#architecture').innerHTML = globalize.translate('DashboardArchitecture', systemInfo.SystemArchitecture); diff --git a/src/controllers/dashboard/mediaLibrary.js b/src/controllers/dashboard/mediaLibrary.js index 06eba37cbd..da345859d9 100644 --- a/src/controllers/dashboard/mediaLibrary.js +++ b/src/controllers/dashboard/mediaLibrary.js @@ -161,7 +161,7 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl showType: false, showLocations: false, showMenu: false, - showNameWithIcon: true + showNameWithIcon: false }); for (var i = 0; i < virtualFolders.length; i++) { @@ -176,7 +176,7 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl $('.btnCardMenu', divVirtualFolders).on('click', function () { showCardMenu(page, this, virtualFolders); }); - divVirtualFolders.querySelector('.addLibrary').addEventListener('click', function () { + divVirtualFolders.querySelector('#addLibrary').addEventListener('click', function () { addVirtualFolder(page); }); $('.editLibrary', divVirtualFolders).on('click', function () { @@ -247,7 +247,12 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl style += 'min-width:33.3%;'; } - html += '
'; + if (virtualFolder.Locations.length == 0) { + html += '
'; + } else { + html += '
'; + } + html += '
'; html += '
'; html += '
'; diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index 45c43c19be..a14fa08aa4 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -53,11 +53,13 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti user: user, share: true }; + return options; } function getProgramScheduleHtml(items) { var html = ''; + html += '
'; html += listView.getListViewHtml({ items: items, @@ -71,6 +73,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti moreButton: false, recordButton: false }); + html += '
'; return html; @@ -143,7 +146,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti instance._currentPlaybackMediaSources = mediaSources; page.querySelector('.trackSelections').classList.remove('hide'); - select.setLabel(globalize.translate('LabelVersion')); var currentValue = select.value; @@ -165,7 +167,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti renderAudioSelections(page, mediaSources); renderSubtitleSelections(page, mediaSources); } - } function renderVideoSelections(page, mediaSources) { @@ -173,9 +174,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti var mediaSource = mediaSources.filter(function (m) { return m.Id === mediaSourceId; })[0]; + var tracks = mediaSource.MediaStreams.filter(function (m) { return m.Type === 'Video'; }); + var select = page.querySelector('.selectVideo'); select.setLabel(globalize.translate('LabelVideo')); var selectedId = tracks.length ? tracks[0].Index : -1; @@ -248,7 +251,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti return 'Video' === m.Type; }); - // This only makes sence on Video items + // This only makes sense on Video items if (videoTracks.length) { var selected = -1 === selectedId ? ' selected' : ''; select.innerHTML = '' + tracks.map(function (v) { @@ -256,7 +259,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti return ''; }).join(''); - if (tracks.length > 1) { + if (tracks.length > 0) { select.removeAttribute('disabled'); } else { select.setAttribute('disabled', 'disabled'); @@ -723,11 +726,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti disableIndicators: true, disableHoverMenu: true, overlayPlayButton: true, - width: dom.getWindowSize().innerWidth * 0.25 + width: dom.getWindowSize().innerWidth * 0.5 }); elem.innerHTML = cardHtml; - imageLoader.lazyChildren(elem); } @@ -1359,7 +1361,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti imageSize: 'large', enableSideMediaInfo: false, highlight: false, - action: layoutManager.tv ? 'resume' : 'none', + action: !layoutManager.desktop ? 'link' : 'none', imagePlayButton: true, includeParentInfoInTitle: false }); diff --git a/src/controllers/playback/nowplaying.js b/src/controllers/playback/nowplaying.js index 98c9945e84..581b5f4b8a 100644 --- a/src/controllers/playback/nowplaying.js +++ b/src/controllers/playback/nowplaying.js @@ -1,22 +1,22 @@ -define(['components/remotecontrol/remotecontrol', 'libraryMenu', 'emby-button'], function (remotecontrolFactory, libraryMenu) { - 'use strict'; +import remotecontrolFactory from 'components/remotecontrol/remotecontrol'; +import libraryMenu from 'libraryMenu'; +import 'emby-button'; - return function (view, params) { - var remoteControl = new remotecontrolFactory(); - remoteControl.init(view, view.querySelector('.remoteControlContent')); - view.addEventListener('viewshow', function (e) { - libraryMenu.setTransparentMenu(true); +export default function (view, params) { + const remoteControl = new remotecontrolFactory(); + remoteControl.init(view, view.querySelector('.remoteControlContent')); + view.addEventListener('viewshow', function (e) { + libraryMenu.setTransparentMenu(true); - if (remoteControl) { - remoteControl.onShow(); - } - }); - view.addEventListener('viewbeforehide', function (e) { - libraryMenu.setTransparentMenu(false); + if (remoteControl) { + remoteControl.onShow(); + } + }); + view.addEventListener('viewbeforehide', function (e) { + libraryMenu.setTransparentMenu(false); - if (remoteControl) { - remoteControl.destroy(); - } - }); - }; -}); + if (remoteControl) { + remoteControl.destroy(); + } + }); +} diff --git a/src/controllers/playback/videoosd.js b/src/controllers/playback/videoosd.js index dd0dc25efd..cf1e579043 100644 --- a/src/controllers/playback/videoosd.js +++ b/src/controllers/playback/videoosd.js @@ -1,5 +1,26 @@ -define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'mediaInfo', 'focusManager', 'imageLoader', 'scrollHelper', 'events', 'connectionManager', 'browser', 'globalize', 'apphost', 'layoutManager', 'userSettings', 'keyboardnavigation', 'scrollStyles', 'emby-slider', 'paper-icon-button-light', 'css!assets/css/videoosd'], function (playbackManager, dom, inputManager, datetime, itemHelper, mediaInfo, focusManager, imageLoader, scrollHelper, events, connectionManager, browser, globalize, appHost, layoutManager, userSettings, keyboardnavigation) { - 'use strict'; +import playbackManager from 'playbackManager'; +import dom from 'dom'; +import inputManager from 'inputManager'; +import datetime from 'datetime'; +import itemHelper from 'itemHelper'; +import mediaInfo from 'mediaInfo'; +import focusManager from 'focusManager'; +import imageLoader from 'imageLoader'; +import scrollHelper from 'scrollHelper'; +import events from 'events'; +import connectionManager from 'connectionManager'; +import browser from 'browser'; +import globalize from 'globalize'; +import appHost from 'apphost'; +import layoutManager from 'layoutManager'; +import * as userSettings from 'userSettings'; +import keyboardnavigation from 'keyboardnavigation'; +import 'scrollStyles'; +import 'emby-slider'; +import 'paper-icon-button-light'; +import 'css!assets/css/videoosd'; + +/* eslint-disable indent */ function seriesImageUrl(item, options) { if ('Episode' !== item.Type) { @@ -49,13 +70,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return document.querySelector('.dialogContainer .dialog.opened'); } - return function (view, params) { + export default function (view, params) { function onVerticalSwipe(e, elem, data) { - var player = currentPlayer; + const player = currentPlayer; if (player) { - var deltaY = data.currentDeltaY; - var windowSize = dom.getWindowSize(); + const deltaY = data.currentDeltaY; + const windowSize = dom.getWindowSize(); if (supportsBrightnessChange && data.clientX < windowSize.innerWidth / 2) { return void doBrightnessTouch(deltaY, player, windowSize.innerHeight); @@ -66,23 +87,23 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function doBrightnessTouch(deltaY, player, viewHeight) { - var delta = -deltaY / viewHeight * 100; - var newValue = playbackManager.getBrightness(player) + delta; + const delta = -deltaY / viewHeight * 100; + let newValue = playbackManager.getBrightness(player) + delta; newValue = Math.min(newValue, 100); newValue = Math.max(newValue, 0); playbackManager.setBrightness(newValue, player); } function doVolumeTouch(deltaY, player, viewHeight) { - var delta = -deltaY / viewHeight * 100; - var newValue = playbackManager.getVolume(player) + delta; + const delta = -deltaY / viewHeight * 100; + let newValue = playbackManager.getVolume(player) + delta; newValue = Math.min(newValue, 100); newValue = Math.max(newValue, 0); playbackManager.setVolume(newValue, player); } function onDoubleClick(e) { - var clientX = e.clientX; + const clientX = e.clientX; if (null != clientX) { if (clientX < dom.getWindowSize().innerWidth / 2) { @@ -98,7 +119,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function getDisplayItem(item) { if ('TvChannel' === item.Type) { - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); return apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (refreshedItem) { return { originalItem: refreshedItem, @@ -124,7 +145,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med connectionManager.getApiClient(item.ServerId).getCurrentUser().then(function (user) { if (user.Policy.EnableLiveTvManagement) { - require(['recordingButton'], function (RecordingButton) { + import('recordingButton').then(({default: RecordingButton}) => { if (recordingButtonManager) { return void recordingButtonManager.refreshItem(item); } @@ -140,22 +161,22 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function updateDisplayItem(itemInfo) { - var item = itemInfo.originalItem; + const item = itemInfo.originalItem; currentItem = item; - var displayItem = itemInfo.displayItem || item; + const displayItem = itemInfo.displayItem || item; updateRecordingButton(displayItem); setPoster(displayItem, item); - var parentName = displayItem.SeriesName || displayItem.Album; + let parentName = displayItem.SeriesName || displayItem.Album; if (displayItem.EpisodeTitle || displayItem.IsSeries) { parentName = displayItem.Name; } setTitle(displayItem, parentName); - var titleElement; - var osdTitle = view.querySelector('.osdTitle'); + let titleElement; + const osdTitle = view.querySelector('.osdTitle'); titleElement = osdTitle; - var displayName = itemHelper.getDisplayName(displayItem, { + let displayName = itemHelper.getDisplayName(displayItem, { includeParentInfo: 'Program' !== displayItem.Type, includeIndexNumber: 'Program' !== displayItem.Type }); @@ -172,7 +193,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med titleElement.classList.add('hide'); } - var mediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(displayItem, { + const mediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(displayItem, { runtime: false, subtitles: false, tomatoes: false, @@ -182,7 +203,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med episodeTitleIndexNumber: 'Program' !== displayItem.Type, programIndicator: false }); - var osdMediaInfo = view.querySelector('.osdMediaInfo'); + const osdMediaInfo = view.querySelector('.osdMediaInfo'); osdMediaInfo.innerHTML = mediaInfoHtml; if (mediaInfoHtml) { @@ -191,8 +212,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med osdMediaInfo.classList.add('hide'); } - var secondaryMediaInfo = view.querySelector('.osdSecondaryMediaInfo'); - var secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, { + const secondaryMediaInfo = view.querySelector('.osdSecondaryMediaInfo'); + const secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, { startDate: false, programTime: false }); @@ -240,7 +261,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function setDisplayTime(elem, date) { - var html; + let html; if (date) { date = datetime.parseISO8601Date(date); @@ -255,7 +276,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function updateNowPlayingInfo(player, state) { - var item = state.NowPlayingItem; + const item = state.NowPlayingItem; currentItem = item; if (!item) { @@ -298,7 +319,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function setTitle(item, parentName) { Emby.Page.setTitle(parentName || ''); - var documentTitle = parentName || (item ? item.Name : null); + const documentTitle = parentName || (item ? item.Name : null); if (documentTitle) { document.title = documentTitle; @@ -306,10 +327,10 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function setPoster(item, secondaryItem) { - var osdPoster = view.querySelector('.osdPoster'); + const osdPoster = view.querySelector('.osdPoster'); if (item) { - var imgUrl = seriesImageUrl(item, { + let imgUrl = seriesImageUrl(item, { maxWidth: osdPoster.clientWidth * 2, type: 'Primary' }) || seriesImageUrl(item, { @@ -385,7 +406,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onHideAnimationComplete(e) { - var elem = e.target; + const elem = e.target; if (elem != osdBottomElement) return; elem.classList.add('hide'); @@ -396,7 +417,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function showMainOsdControls() { if (!currentVisibleMenu) { - var elem = osdBottomElement; + const elem = osdBottomElement; currentVisibleMenu = 'osd'; clearHideAnimationEventListeners(elem); elem.classList.remove('hide'); @@ -413,7 +434,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function hideMainOsdControls() { if ('osd' === currentVisibleMenu) { - var elem = osdBottomElement; + const elem = osdBottomElement; clearHideAnimationEventListeners(elem); elem.classList.add('videoOsdBottom-hidden'); dom.addEventListener(elem, transitionEndEventName, onHideAnimationComplete, { @@ -442,9 +463,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function onPointerMove(e) { if ('mouse' === (e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'))) { - var eventX = e.screenX || 0; - var eventY = e.screenY || 0; - var obj = lastPointerMoveData; + const eventX = e.screenX || 0; + const eventY = e.screenY || 0; + const obj = lastPointerMoveData; if (!obj) { lastPointerMoveData = { @@ -465,7 +486,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onInputCommand(e) { - var player = currentPlayer; + const player = currentPlayer; switch (e.detail.command) { case 'left': @@ -524,7 +545,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onRecordingCommand() { - var btnRecord = view.querySelector('.btnRecord'); + const btnRecord = view.querySelector('.btnRecord'); if (!btnRecord.classList.contains('hide')) { btnRecord.click(); @@ -551,7 +572,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onStateChanged(event, state) { - var player = this; + const player = this; if (state.NowPlayingItem) { isEnabled = true; @@ -569,21 +590,21 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function onVolumeChanged(e) { if (isEnabled) { - var player = this; + const player = this; updatePlayerVolumeState(player, player.isMuted(), player.getVolume()); } } function onPlaybackStart(e, state) { console.debug('nowplaying event: ' + e.type); - var player = this; + const player = this; onStateChanged.call(player, e, state); resetUpNextDialog(); } function resetUpNextDialog() { comingUpNextDisplayed = false; - var dlg = currentUpNextDialog; + const dlg = currentUpNextDialog; if (dlg) { dlg.destroy(); @@ -603,8 +624,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onMediaStreamsChanged(e) { - var player = this; - var state = playbackManager.getPlayerState(player); + const player = this; + const state = playbackManager.getPlayerState(player); onStateChanged.call(player, { type: 'init' }, state); @@ -624,7 +645,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med currentPlayer = player; if (!player) return; } - var state = playbackManager.getPlayerState(player); + const state = playbackManager.getPlayerState(player); onStateChanged.call(player, { type: 'init' }, state); @@ -649,7 +670,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med destroyStats(); destroySubtitleSync(); resetUpNextDialog(); - var player = currentPlayer; + const player = currentPlayer; if (player) { events.off(player, 'playbackstart', onPlaybackStart); @@ -667,15 +688,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function onTimeUpdate(e) { // Test for 'currentItem' is required for Firefox since its player spams 'timeupdate' events even being at breakpoint if (isEnabled && currentItem) { - var now = new Date().getTime(); + const now = new Date().getTime(); if (!(now - lastUpdateTime < 700)) { lastUpdateTime = now; - var player = this; + const player = this; currentRuntimeTicks = playbackManager.duration(player); - var currentTime = playbackManager.currentTime(player); + const currentTime = playbackManager.currentTime(player); updateTimeDisplay(currentTime, currentRuntimeTicks, playbackManager.playbackStartTime(player), playbackManager.getBufferedRanges(player)); - var item = currentItem; + const item = currentItem; refreshProgramInfoIfNeeded(player, item); showComingUpNextIfNeeded(player, item, currentTime, currentRuntimeTicks); } @@ -684,9 +705,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function showComingUpNextIfNeeded(player, currentItem, currentTimeTicks, runtimeTicks) { if (runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && 'Episode' === currentItem.Type && userSettings.enableNextVideoInfoOverlay()) { - var showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30; - var showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4; - var timeRemainingTicks = runtimeTicks - currentTimeTicks; + const showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30; + const showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4; + const timeRemainingTicks = runtimeTicks - currentTimeTicks; if (currentTimeTicks >= showAtTicks && runtimeTicks >= 6e9 && timeRemainingTicks >= 2e8) { showComingUpNext(player); @@ -701,7 +722,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function showComingUpNext(player) { - require(['upNextDialog'], function (UpNextDialog) { + import('upNextDialog').then(({default: UpNextDialog}) => { if (!(currentVisibleMenu || currentUpNextDialog)) { currentVisibleMenu = 'upnext'; comingUpNextDisplayed = true; @@ -719,15 +740,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function refreshProgramInfoIfNeeded(player, item) { if ('TvChannel' === item.Type) { - var program = item.CurrentProgram; + const program = item.CurrentProgram; if (program && program.EndDate) { try { - var endDate = datetime.parseISO8601Date(program.EndDate); + const endDate = datetime.parseISO8601Date(program.EndDate); if (new Date().getTime() >= endDate.getTime()) { console.debug('program info needs to be refreshed'); - var state = playbackManager.getPlayerState(player); + const state = playbackManager.getPlayerState(player); onStateChanged.call(player, { type: 'init' }, state); @@ -755,9 +776,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function updatePlayerStateInternal(event, player, state) { - var playState = state.PlayState || {}; + const playState = state.PlayState || {}; updatePlayPauseState(playState.IsPaused); - var supportedCommands = playbackManager.getSupportedCommands(player); + const supportedCommands = playbackManager.getSupportedCommands(player); currentPlayerSupportedCommands = supportedCommands; supportsBrightnessChange = -1 !== supportedCommands.indexOf('SetBrightness'); updatePlayerVolumeState(player, playState.IsMuted, playState.VolumeLevel); @@ -768,7 +789,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med btnFastForward.disabled = !playState.CanSeek; btnRewind.disabled = !playState.CanSeek; - var nowPlayingItem = state.NowPlayingItem || {}; + const nowPlayingItem = state.NowPlayingItem || {}; playbackStartTimeTicks = playState.PlaybackStartTimeTicks; updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playState.PlaybackStartTimeTicks, playState.BufferedRanges || []); updateNowPlayingInfo(player, state); @@ -779,7 +800,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med view.querySelector('.btnVideoOsdSettings').classList.add('hide'); } - var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks; + const isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks; nowPlayingPositionSlider.setIsClear(isProgressClear); if (nowPlayingItem.RunTimeTicks) { @@ -816,12 +837,12 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med if (enableProgressByTimeOfDay) { if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) { if (programStartDateMs && programEndDateMs) { - var currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4; - var programRuntimeMs = programEndDateMs - programStartDateMs; + const currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4; + const programRuntimeMs = programEndDateMs - programStartDateMs; if (nowPlayingPositionSlider.value = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs), bufferedRanges.length) { - var rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4); - var rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4); + const rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4); + const rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4); nowPlayingPositionSlider.setBufferedRanges([{ start: rangeStart, end: rangeEnd @@ -840,7 +861,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } else { if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) { if (runtimeTicks) { - var pct = positionTicks / runtimeTicks; + let pct = positionTicks / runtimeTicks; pct *= 100; nowPlayingPositionSlider.value = pct; } else { @@ -864,9 +885,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function updatePlayerVolumeState(player, isMuted, volumeLevel) { - var supportedCommands = currentPlayerSupportedCommands; - var showMuteButton = true; - var showVolumeSlider = true; + const supportedCommands = currentPlayerSupportedCommands; + let showMuteButton = true; + let showVolumeSlider = true; if (-1 === supportedCommands.indexOf('Mute')) { showMuteButton = false; @@ -914,8 +935,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function updatePlaylist(player) { - var btnPreviousTrack = view.querySelector('.btnPreviousTrack'); - var btnNextTrack = view.querySelector('.btnNextTrack'); + const btnPreviousTrack = view.querySelector('.btnPreviousTrack'); + const btnNextTrack = view.querySelector('.btnNextTrack'); btnPreviousTrack.classList.remove('hide'); btnNextTrack.classList.remove('hide'); btnNextTrack.disabled = false; @@ -928,7 +949,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return; } - var html = datetime.getDisplayRunningTime(ticks); + let html = datetime.getDisplayRunningTime(ticks); if (divider) { html = ' / ' + html; @@ -938,15 +959,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onSettingsButtonClick(e) { - var btn = this; + const btn = this; - require(['playerSettingsMenu'], function (playerSettingsMenu) { - var player = currentPlayer; + import('playerSettingsMenu').then(({default: playerSettingsMenu}) => { + const player = currentPlayer; if (player) { // show subtitle offset feature only if player and media support it - var showSubOffset = playbackManager.supportSubtitleOffset(player) && + const showSubOffset = playbackManager.supportSubtitleOffset(player) && playbackManager.canHandleOffsetOnCurrentSubtitle(player); playerSettingsMenu.show({ @@ -969,7 +990,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med if ('stats' === selectedOption) { toggleStats(); } else if ('suboffset' === selectedOption) { - var player = currentPlayer; + const player = currentPlayer; if (player) { playbackManager.enableShowingSubtitleOffset(player); toggleSubtitleSync(); @@ -978,8 +999,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function toggleStats() { - require(['playerStats'], function (PlayerStats) { - var player = currentPlayer; + import('playerStats').then(({default: PlayerStats}) => { + const player = currentPlayer; if (player) { if (statsOverlay) { @@ -1001,11 +1022,11 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function showAudioTrackSelection() { - var player = currentPlayer; - var audioTracks = playbackManager.audioTracks(player); - var currentIndex = playbackManager.getAudioStreamIndex(player); - var menuItems = audioTracks.map(function (stream) { - var opt = { + const player = currentPlayer; + const audioTracks = playbackManager.audioTracks(player); + const currentIndex = playbackManager.getAudioStreamIndex(player); + const menuItems = audioTracks.map(function (stream) { + const opt = { name: stream.DisplayTitle, id: stream.Index }; @@ -1016,15 +1037,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return opt; }); - var positionTo = this; + const positionTo = this; - require(['actionsheet'], function (actionsheet) { + import('actionsheet').then(({default: actionsheet}) => { actionsheet.show({ items: menuItems, title: globalize.translate('Audio'), positionTo: positionTo }).then(function (id) { - var index = parseInt(id); + const index = parseInt(id); if (index !== currentIndex) { playbackManager.setAudioStreamIndex(index, player); @@ -1038,9 +1059,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function showSubtitleTrackSelection() { - var player = currentPlayer; - var streams = playbackManager.subtitleTracks(player); - var currentIndex = playbackManager.getSubtitleStreamIndex(player); + const player = currentPlayer; + const streams = playbackManager.subtitleTracks(player); + let currentIndex = playbackManager.getSubtitleStreamIndex(player); if (null == currentIndex) { currentIndex = -1; @@ -1050,8 +1071,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med Index: -1, DisplayTitle: globalize.translate('Off') }); - var menuItems = streams.map(function (stream) { - var opt = { + const menuItems = streams.map(function (stream) { + const opt = { name: stream.DisplayTitle, id: stream.Index }; @@ -1062,15 +1083,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return opt; }); - var positionTo = this; + const positionTo = this; - require(['actionsheet'], function (actionsheet) { + import('actionsheet').then(({default: actionsheet}) => { actionsheet.show({ title: globalize.translate('Subtitles'), items: menuItems, positionTo: positionTo }).then(function (id) { - var index = parseInt(id); + const index = parseInt(id); if (index !== currentIndex) { playbackManager.setSubtitleStreamIndex(index, player); @@ -1086,8 +1107,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function toggleSubtitleSync(action) { - require(['subtitleSync'], function (SubtitleSync) { - var player = currentPlayer; + import('subtitleSync').then(({default: SubtitleSync}) => { + const player = currentPlayer; if (subtitleSyncOverlay) { subtitleSyncOverlay.toggle(action); } else if (player) { @@ -1107,12 +1128,12 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med * Clicked element. * To skip 'click' handling on Firefox/Edge. */ - var clickedElement; + let clickedElement; function onKeyDown(e) { clickedElement = e.target; - var key = keyboardnavigation.getKeyName(e); + const key = keyboardnavigation.getKeyName(e); if (!currentVisibleMenu && 32 === e.keyCode) { playbackManager.playPause(currentPlayer); @@ -1216,10 +1237,11 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med case '6': case '7': case '8': - case '9': - var percent = parseInt(key, 10) * 10; + case '9': { + const percent = parseInt(key, 10) * 10; playbackManager.seekPercent(percent, currentPlayer); break; + } } } @@ -1269,11 +1291,11 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function getChapterBubbleHtml(apiClient, item, chapters, positionTicks) { - var chapter; - var index = -1; + let chapter; + let index = -1; - for (var i = 0, length = chapters.length; i < length; i++) { - var currentChapter = chapters[i]; + for (let i = 0, length = chapters.length; i < length; i++) { + const currentChapter = chapters[i]; if (positionTicks >= currentChapter.StartPositionTicks) { chapter = currentChapter; @@ -1285,10 +1307,10 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return null; } - var src = getImgUrl(item, chapter, index, 400, apiClient); + const src = getImgUrl(item, chapter, index, 400, apiClient); if (src) { - var html = '
'; + let html = '
'; html += ''; html += '
'; html += '
'; @@ -1304,15 +1326,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return null; } - var playPauseClickTimeout; + let playPauseClickTimeout; function onViewHideStopPlayback() { if (playbackManager.isPlayingVideo()) { - require(['shell'], function (shell) { + import('shell').then(({default: shell}) => { shell.disableFullscreen(); }); clearTimeout(playPauseClickTimeout); - var player = currentPlayer; + const player = currentPlayer; view.removeEventListener('viewbeforehide', onViewHideStopPlayback); releaseCurrentPlayer(); playbackManager.stop(player); @@ -1327,43 +1349,43 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } } - require(['shell'], function (shell) { + import('shell').then(({default: shell}) => { shell.enableFullscreen(); }); - var currentPlayer; - var comingUpNextDisplayed; - var currentUpNextDialog; - var isEnabled; - var currentItem; - var recordingButtonManager; - var enableProgressByTimeOfDay; - var supportsBrightnessChange; - var currentVisibleMenu; - var statsOverlay; - var osdHideTimeout; - var lastPointerMoveData; - var self = this; - var currentPlayerSupportedCommands = []; - var currentRuntimeTicks = 0; - var lastUpdateTime = 0; - var programStartDateMs = 0; - var programEndDateMs = 0; - var playbackStartTimeTicks = 0; - var subtitleSyncOverlay; - var nowPlayingVolumeSlider = view.querySelector('.osdVolumeSlider'); - var nowPlayingVolumeSliderContainer = view.querySelector('.osdVolumeSliderContainer'); - var nowPlayingPositionSlider = view.querySelector('.osdPositionSlider'); - var nowPlayingPositionText = view.querySelector('.osdPositionText'); - var nowPlayingDurationText = view.querySelector('.osdDurationText'); - var startTimeText = view.querySelector('.startTimeText'); - var endTimeText = view.querySelector('.endTimeText'); - var endsAtText = view.querySelector('.endsAtText'); - var btnRewind = view.querySelector('.btnRewind'); - var btnFastForward = view.querySelector('.btnFastForward'); - var transitionEndEventName = dom.whichTransitionEvent(); - var headerElement = document.querySelector('.skinHeader'); - var osdBottomElement = document.querySelector('.videoOsdBottom-maincontrols'); + let currentPlayer; + let comingUpNextDisplayed; + let currentUpNextDialog; + let isEnabled; + let currentItem; + let recordingButtonManager; + let enableProgressByTimeOfDay; + let supportsBrightnessChange; + let currentVisibleMenu; + let statsOverlay; + let osdHideTimeout; + let lastPointerMoveData; + const self = this; + let currentPlayerSupportedCommands = []; + let currentRuntimeTicks = 0; + let lastUpdateTime = 0; + let programStartDateMs = 0; + let programEndDateMs = 0; + let playbackStartTimeTicks = 0; + let subtitleSyncOverlay; + const nowPlayingVolumeSlider = view.querySelector('.osdVolumeSlider'); + const nowPlayingVolumeSliderContainer = view.querySelector('.osdVolumeSliderContainer'); + const nowPlayingPositionSlider = view.querySelector('.osdPositionSlider'); + const nowPlayingPositionText = view.querySelector('.osdPositionText'); + const nowPlayingDurationText = view.querySelector('.osdDurationText'); + const startTimeText = view.querySelector('.startTimeText'); + const endTimeText = view.querySelector('.endTimeText'); + const endsAtText = view.querySelector('.endsAtText'); + const btnRewind = view.querySelector('.btnRewind'); + const btnFastForward = view.querySelector('.btnFastForward'); + const transitionEndEventName = dom.whichTransitionEvent(); + const headerElement = document.querySelector('.skinHeader'); + const osdBottomElement = document.querySelector('.videoOsdBottom-maincontrols'); nowPlayingPositionSlider.enableKeyboardDragging(); nowPlayingVolumeSlider.enableKeyboardDragging(); @@ -1416,7 +1438,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med passive: true }); } catch (e) { - require(['appRouter'], function(appRouter) { + import('appRouter').then(({default: appRouter}) => { appRouter.goHome(); }); } @@ -1493,15 +1515,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med destroyStats(); destroySubtitleSync(); }); - var lastPointerDown = 0; + let lastPointerDown = 0; /* eslint-disable-next-line compat/compat */ dom.addEventListener(view, window.PointerEvent ? 'pointerdown' : 'click', function (e) { if (dom.parentWithClass(e.target, ['videoOsdBottom', 'upNextContainer'])) { return void showOsd(); } - var pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'); - var now = new Date().getTime(); + const pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'); + const now = new Date().getTime(); switch (pointerType) { case 'touch': @@ -1539,7 +1561,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med if (browser.touch) { dom.addEventListener(view, 'dblclick', onDoubleClick, {}); } else { - var options = { passive: true }; + const options = { passive: true }; dom.addEventListener(view, 'dblclick', function () { playbackManager.toggleFullscreen(currentPlayer); }, options); @@ -1554,13 +1576,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med }); nowPlayingPositionSlider.addEventListener('change', function () { - var player = currentPlayer; + const player = currentPlayer; if (player) { - var newPercent = parseFloat(this.value); + const newPercent = parseFloat(this.value); if (enableProgressByTimeOfDay) { - var seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4; + let seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4; seekAirTimeTicks += 1e4 * programStartDateMs; seekAirTimeTicks -= playbackStartTimeTicks; playbackManager.seek(seekAirTimeTicks, player); @@ -1574,7 +1596,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med showOsd(); if (enableProgressByTimeOfDay) { if (programStartDateMs && programEndDateMs) { - var ms = programEndDateMs - programStartDateMs; + let ms = programEndDateMs - programStartDateMs; ms /= 100; ms *= value; ms += programStartDateMs; @@ -1588,13 +1610,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return '--:--'; } - var ticks = currentRuntimeTicks; + let ticks = currentRuntimeTicks; ticks /= 100; ticks *= value; - var item = currentItem; + const item = currentItem; if (item && item.Chapters && item.Chapters.length && item.Chapters[0].ImageTag) { - var html = getChapterBubbleHtml(connectionManager.getApiClient(item.ServerId), item, item.Chapters, ticks); + let html = getChapterBubbleHtml(connectionManager.getApiClient(item.ServerId), item, item.Chapters, ticks); if (html) { return html; @@ -1627,7 +1649,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med if (browser.touch) { (function () { - require(['touchHelper'], function (TouchHelper) { + import('touchHelper').then(({default: TouchHelper}) => { self.touchHelper = new TouchHelper(view, { swipeYThreshold: 30, triggerOnMove: true, @@ -1639,5 +1661,6 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med }); })(); } - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/user/display.js b/src/controllers/user/display.js index 26c75f209a..a400c50ccf 100644 --- a/src/controllers/user/display.js +++ b/src/controllers/user/display.js @@ -1,20 +1,23 @@ -define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySettings, userSettings, autoFocuser) { - 'use strict'; +import DisplaySettings from 'displaySettings'; +import * as userSettings from 'userSettings'; +import autoFocuser from 'autoFocuser'; + +/* eslint-disable indent */ // Shortcuts const UserSettings = userSettings.UserSettings; - return function (view, params) { + export default function (view, params) { function onBeforeUnload(e) { if (hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; } } - var settingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + let settingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); view.addEventListener('viewshow', function () { window.addEventListener('beforeunload', onBeforeUnload); @@ -26,28 +29,23 @@ define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySett userId: userId, element: view.querySelector('.settingsContainer'), userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, + enableSaveButton: true, + enableSaveConfirmation: true, autoFocus: autoFocuser.isEnabled() }); } }); + view.addEventListener('change', function () { hasChanges = true; }); - view.addEventListener('viewbeforehide', function () { - window.removeEventListener('beforeunload', onBeforeUnload); - hasChanges = false; - if (settingsInstance) { - settingsInstance.submit(); - } - }); view.addEventListener('viewdestroy', function () { if (settingsInstance) { settingsInstance.destroy(); settingsInstance = null; } }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/user/home.js b/src/controllers/user/home.js index 8f826c425d..e7058fd3ac 100644 --- a/src/controllers/user/home.js +++ b/src/controllers/user/home.js @@ -1,20 +1,27 @@ -define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (HomescreenSettings, dom, globalize, loading, userSettings, autoFocuser) { - 'use strict'; +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'; + +/* eslint-disable indent */ // Shortcuts const UserSettings = userSettings.UserSettings; - return function (view, params) { + export default function (view, params) { function onBeforeUnload(e) { if (hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; } } - var homescreenSettingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + let homescreenSettingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); view.addEventListener('viewshow', function () { window.addEventListener('beforeunload', onBeforeUnload); @@ -26,27 +33,23 @@ define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'au userId: userId, element: view.querySelector('.homeScreenSettingsContainer'), userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, + enableSaveButton: true, + enableSaveConfirmation: true, autoFocus: autoFocuser.isEnabled() }); } }); + view.addEventListener('change', function () { hasChanges = true; }); - view.addEventListener('viewbeforehide', function () { - hasChanges = false; - if (homescreenSettingsInstance) { - homescreenSettingsInstance.submit(); - } - }); view.addEventListener('viewdestroy', function () { if (homescreenSettingsInstance) { homescreenSettingsInstance.destroy(); homescreenSettingsInstance = null; } }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/user/playback.js b/src/controllers/user/playback.js index 02a718eb8c..5bcf055cd3 100644 --- a/src/controllers/user/playback.js +++ b/src/controllers/user/playback.js @@ -1,20 +1,27 @@ -define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (PlaybackSettings, dom, globalize, loading, userSettings, autoFocuser) { - 'use strict'; +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'; + +/* eslint-disable indent */ // Shortcuts const UserSettings = userSettings.UserSettings; - return function (view, params) { + export default function (view, params) { function onBeforeUnload(e) { if (hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; } } - var settingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + let settingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); view.addEventListener('viewshow', function () { window.addEventListener('beforeunload', onBeforeUnload); @@ -26,27 +33,23 @@ define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'auto userId: userId, element: view.querySelector('.settingsContainer'), userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, + enableSaveButton: true, + enableSaveConfirmation: true, autoFocus: autoFocuser.isEnabled() }); } }); + view.addEventListener('change', function () { hasChanges = true; }); - view.addEventListener('viewbeforehide', function () { - hasChanges = false; - if (settingsInstance) { - settingsInstance.submit(); - } - }); view.addEventListener('viewdestroy', function () { if (settingsInstance) { settingsInstance.destroy(); settingsInstance = null; } }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/user/subtitles.js b/src/controllers/user/subtitles.js index 7e7e7fb8a9..82f5270a4e 100644 --- a/src/controllers/user/subtitles.js +++ b/src/controllers/user/subtitles.js @@ -1,20 +1,23 @@ -define(['subtitleSettings', 'userSettings', 'autoFocuser'], function (SubtitleSettings, userSettings, autoFocuser) { - 'use strict'; +import SubtitleSettings from 'subtitleSettings'; +import * as userSettings from 'userSettings'; +import autoFocuser from 'autoFocuser'; + +/* eslint-disable indent */ // Shortcuts const UserSettings = userSettings.UserSettings; - return function (view, params) { + export default function (view, params) { function onBeforeUnload(e) { if (hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; } } - var subtitleSettingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + let subtitleSettingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); view.addEventListener('viewshow', function () { window.addEventListener('beforeunload', onBeforeUnload); @@ -26,27 +29,23 @@ define(['subtitleSettings', 'userSettings', 'autoFocuser'], function (SubtitleSe userId: userId, element: view.querySelector('.settingsContainer'), userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, + enableSaveButton: true, + enableSaveConfirmation: true, autoFocus: autoFocuser.isEnabled() }); } }); + view.addEventListener('change', function () { hasChanges = true; }); - view.addEventListener('viewbeforehide', function () { - hasChanges = false; - if (subtitleSettingsInstance) { - subtitleSettingsInstance.submit(); - } - }); view.addEventListener('viewdestroy', function () { if (subtitleSettingsInstance) { subtitleSettingsInstance.destroy(); subtitleSettingsInstance = null; } }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/elements/emby-itemscontainer/emby-itemscontainer.js b/src/elements/emby-itemscontainer/emby-itemscontainer.js index 231e681047..9148a11fdb 100644 --- a/src/elements/emby-itemscontainer/emby-itemscontainer.js +++ b/src/elements/emby-itemscontainer/emby-itemscontainer.js @@ -30,7 +30,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager', // check for serverId, it won't be present on selectserver if (card && card.getAttribute('data-serverid')) { - inputManager.trigger('menu', { + inputManager.handleCommand('menu', { sourceElement: card }); diff --git a/src/elements/emby-tabs/emby-tabs.css b/src/elements/emby-tabs/emby-tabs.css index 355f904cb8..fe29f46143 100644 --- a/src/elements/emby-tabs/emby-tabs.css +++ b/src/elements/emby-tabs/emby-tabs.css @@ -31,11 +31,6 @@ .emby-tabs-slider { position: relative; - overflow: hidden; -} - -.layout-mobile .emby-tabs-slider { - overflow: auto; } .tabContent:not(.is-active) { diff --git a/src/login.html b/src/login.html index 8e48901c11..fd52b4bf58 100644 --- a/src/login.html +++ b/src/login.html @@ -1,7 +1,9 @@ -
+
-
-

${HeaderPleaseSignIn}

+ +
+

${HeaderPleaseSignIn}

+
@@ -29,8 +31,6 @@ ${ButtonCancel}
-
-
diff --git a/src/nowplaying.html b/src/nowplaying.html index 9460cb814b..592807737f 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -5,7 +5,7 @@
- +
@@ -15,9 +15,9 @@
- +
- +
@@ -25,20 +25,20 @@
- +
- +
- + - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@
- + @@ -74,7 +74,7 @@ - +