diff --git a/dashboard-ui/bower_components/emby-webcomponents/.bower.json b/dashboard-ui/bower_components/emby-webcomponents/.bower.json index a1b7bb646..73b63d29e 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/.bower.json +++ b/dashboard-ui/bower_components/emby-webcomponents/.bower.json @@ -14,12 +14,12 @@ }, "devDependencies": {}, "ignore": [], - "version": "1.4.320", - "_release": "1.4.320", + "version": "1.4.321", + "_release": "1.4.321", "_resolution": { "type": "version", - "tag": "1.4.320", - "commit": "5b3dc54cf24d4f615a59e5954726231e446cfced" + "tag": "1.4.321", + "commit": "fb270e69c8391f62e762ee03d77a7b8a495c5a6f" }, "_source": "https://github.com/MediaBrowser/emby-webcomponents.git", "_target": "^1.2.1", diff --git a/dashboard-ui/bower_components/emby-webcomponents/backdrop/backdrop.js b/dashboard-ui/bower_components/emby-webcomponents/backdrop/backdrop.js index defcbdc20..57b19ce5e 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/backdrop/backdrop.js +++ b/dashboard-ui/bower_components/emby-webcomponents/backdrop/backdrop.js @@ -51,15 +51,21 @@ return; } - setTimeout(function () { - + var onAnimationComplete = function () { + dom.removeEventListener(backdropImage, 'animationend', onAnimationComplete, { + once: true + }); if (backdropImage === currentAnimatingElement) { currentAnimatingElement = null; } if (existingBackdropImage && existingBackdropImage.parentNode) { existingBackdropImage.parentNode.removeChild(existingBackdropImage); } - }, 800); + }; + + dom.addEventListener(backdropImage, 'animationend', onAnimationComplete, { + once: true + }); internalBackdrop(true); }; diff --git a/dashboard-ui/bower_components/emby-webcomponents/dialoghelper/dialoghelper.js b/dashboard-ui/bower_components/emby-webcomponents/dialoghelper/dialoghelper.js index 7c4ca8c98..d2e00e0a1 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/dialoghelper/dialoghelper.js +++ b/dashboard-ui/bower_components/emby-webcomponents/dialoghelper/dialoghelper.js @@ -3,6 +3,24 @@ var globalOnOpenCallback; + function enableAnimation() { + + if (browser.animate) { + return true; + } + + if (browser.edge) { + return true; + } + + // An indication of an older browser + if (browser.noFlex) { + return false; + } + + return true; + } + function removeCenterFocus(dlg) { if (layoutManager.tv) { @@ -136,10 +154,9 @@ backdropParent.parentNode.insertBefore(backdrop, backdropParent); dlg.backdrop = backdrop; - // Doing this immediately causes the opacity to jump immediately without animating - setTimeout(function () { - backdrop.classList.add('dialogBackdropOpened'); - }, 0); + // trigger reflow or the backdrop will not animate + void backdrop.offsetWidth; + backdrop.classList.add('dialogBackdropOpened'); dom.addEventListener((dlg.dialogContainer || backdrop), 'click', function (e) { if (e.target === dlg.dialogContainer) { @@ -226,27 +243,59 @@ } }; - setTimeout(onAnimationFinish, dlg.animationConfig.entry.timing.duration); + if (enableAnimation()) { + + var onFinish = function () { + dom.removeEventListener(dlg, 'animationend', onFinish, { + once: true + }); + onAnimationFinish(); + }; + dom.addEventListener(dlg, 'animationend', onFinish, { + once: true + }); + return; + } + + onAnimationFinish(); } function animateDialogClose(dlg, onAnimationFinish) { - switch (dlg.animationConfig.exit.name) { + if (enableAnimation()) { - case 'fadeout': - dlg.style.animation = 'fadeout ' + dlg.animationConfig.exit.timing.duration + 'ms ease-out normal both'; - break; - case 'scaledown': - dlg.style.animation = 'scaledown ' + dlg.animationConfig.exit.timing.duration + 'ms ease-out normal both'; - break; - case 'slidedown': - dlg.style.animation = 'slidedown ' + dlg.animationConfig.exit.timing.duration + 'ms ease-out normal both'; - break; - default: - break; + var animated = true; + switch (dlg.animationConfig.exit.name) { + + case 'fadeout': + dlg.style.animation = 'fadeout ' + dlg.animationConfig.exit.timing.duration + 'ms ease-out normal both'; + break; + case 'scaledown': + dlg.style.animation = 'scaledown ' + dlg.animationConfig.exit.timing.duration + 'ms ease-out normal both'; + break; + case 'slidedown': + dlg.style.animation = 'slidedown ' + dlg.animationConfig.exit.timing.duration + 'ms ease-out normal both'; + break; + default: + animated = false; + break; + } + var onFinish = function () { + dom.removeEventListener(dlg, 'animationend', onFinish, { + once: true + }); + onAnimationFinish(); + }; + dom.addEventListener(dlg, 'animationend', onFinish, { + once: true + }); + + if (animated) { + return; + } } - setTimeout(onAnimationFinish, dlg.animationConfig.exit.timing.duration); + onAnimationFinish(); } function shouldLockDocumentScroll(options) { @@ -270,15 +319,26 @@ var backdrop = dlg.backdrop; - if (backdrop) { - dlg.backdrop = null; + if (!backdrop) { + return; + } + + dlg.backdrop = null; + + var onAnimationFinish = function () { + backdrop.parentNode.removeChild(backdrop); + }; + + if (enableAnimation()) { backdrop.classList.remove('dialogBackdropOpened'); - setTimeout(function () { - backdrop.parentNode.removeChild(backdrop); - }, 300); + // this is not firing animatonend + setTimeout(onAnimationFinish, 300); + return; } + + onAnimationFinish(); } function centerFocus(elem, horiz, on) { @@ -375,19 +435,21 @@ dlg.classList.add('dialog-' + options.size); } - switch (dlg.animationConfig.entry.name) { + if (enableAnimation()) { + switch (dlg.animationConfig.entry.name) { - case 'fadein': - dlg.style.animation = 'fadein ' + entryAnimationDuration + 'ms ease-out normal'; - break; - case 'scaleup': - dlg.style.animation = 'scaleup ' + entryAnimationDuration + 'ms ease-out normal both'; - break; - case 'slideup': - dlg.style.animation = 'slideup ' + entryAnimationDuration + 'ms ease-out normal'; - break; - default: - break; + case 'fadein': + dlg.style.animation = 'fadein ' + entryAnimationDuration + 'ms ease-out normal'; + break; + case 'scaleup': + dlg.style.animation = 'scaleup ' + entryAnimationDuration + 'ms ease-out normal both'; + break; + case 'slideup': + dlg.style.animation = 'slideup ' + entryAnimationDuration + 'ms ease-out normal'; + break; + default: + break; + } } return dlg; diff --git a/dashboard-ui/bower_components/emby-webcomponents/registrationservices/registrationservices.js b/dashboard-ui/bower_components/emby-webcomponents/registrationservices/registrationservices.js index a1759a6f0..52a32e4f1 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/registrationservices/registrationservices.js +++ b/dashboard-ui/bower_components/emby-webcomponents/registrationservices/registrationservices.js @@ -151,7 +151,7 @@ console.log('validateFeature: ' + feature); - return iapManager.isUnlockedByDefault(feature).then(function () { + return iapManager.isUnlockedByDefault(feature, options).then(function () { return showPeriodicMessageIfNeeded(feature); diff --git a/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewcontainer-lite.js b/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewcontainer-lite.js index 59569880a..b0fa957a4 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewcontainer-lite.js +++ b/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewcontainer-lite.js @@ -1,4 +1,4 @@ -define(['browser', 'css!./viewcontainer-lite'], function (browser) { +define(['browser', 'dom', 'css!./viewcontainer-lite'], function (browser, dom) { 'use strict'; var mainAnimatedPages = document.querySelector('.mainAnimatedPages'); @@ -140,7 +140,16 @@ define(['browser', 'css!./viewcontainer-lite'], function (browser) { currentAnimations = animations; - setTimeout(resolve, duration); + var onAnimationComplete = function () { + dom.removeEventListener(newAnimatedPage, 'animationend', onAnimationComplete, { + once: true + }); + resolve(); + }; + + dom.addEventListener(newAnimatedPage, 'animationend', onAnimationComplete, { + once: true + }); }); } @@ -161,7 +170,16 @@ define(['browser', 'css!./viewcontainer-lite'], function (browser) { currentAnimations = animations; - setTimeout(resolve, duration); + var onAnimationComplete = function () { + dom.removeEventListener(newAnimatedPage, 'animationend', onAnimationComplete, { + once: true + }); + resolve(); + }; + + dom.addEventListener(newAnimatedPage, 'animationend', onAnimationComplete, { + once: true + }); }); } diff --git a/dashboard-ui/itemdetails.html b/dashboard-ui/itemdetails.html index 963e8016d..7e565797c 100644 --- a/dashboard-ui/itemdetails.html +++ b/dashboard-ui/itemdetails.html @@ -107,6 +107,12 @@
+
+

+ ${HeaderUpcomingOnTV} +

+
+

diff --git a/dashboard-ui/scripts/itemdetailpage.js b/dashboard-ui/scripts/itemdetailpage.js index 24f91594e..842fc761b 100644 --- a/dashboard-ui/scripts/itemdetailpage.js +++ b/dashboard-ui/scripts/itemdetailpage.js @@ -446,6 +446,11 @@ page.querySelector('#childrenCollapsible').classList.add('hide'); } + if (item.Type == 'Series') { + + renderSeriesSchedule(page, item, user); + } + if (item.Type == 'Series') { renderNextUp(page, item, user); @@ -934,20 +939,21 @@ } var supportsImageAnalysis = appHost.supports('imageanalysis'); + var cardLayout = supportsImageAnalysis && (item.Type == "MusicAlbum" || item.Type == "Game" || item.Type == "MusicArtist"); html += cardBuilder.getCardsHtml({ items: result.Items, shape: shape, showParentTitle: item.Type == "MusicAlbum", - centerText: !supportsImageAnalysis, + centerText: !cardLayout, showTitle: item.Type == "MusicAlbum" || item.Type == "Game" || item.Type == "MusicArtist", context: context, lazy: true, showDetailsMenu: true, coverImage: item.Type == "MusicAlbum" || item.Type == "MusicArtist", overlayPlayButton: true, - cardLayout: supportsImageAnalysis && (item.Type == "MusicAlbum" || item.Type == "Game" || item.Type == "MusicArtist"), - vibrant: supportsImageAnalysis + cardLayout: cardLayout, + vibrant: cardLayout && supportsImageAnalysis }); html += '

'; @@ -1242,10 +1248,49 @@ function renderChannelGuide(page, item, user) { - require('scripts/livetvcomponents,scripts/livetvchannel,livetvcss'.split(','), function () { + require('scripts/livetvchannel,scripts/livetvcomponents,livetvcss'.split(','), function (liveTvChannelPage) { + liveTvChannelPage.renderPrograms(page, item.Id); + }); + } - LiveTvChannelPage.renderPrograms(page, item.Id); + function renderSeriesSchedule(page, item, user) { + + return; + ApiClient.getLiveTvPrograms({ + + UserId: Dashboard.getCurrentUserId(), + HasAired: false, + SortBy: "StartDate", + EnableTotalRecordCount: false, + EnableImages: false, + ImageTypeLimit: 0, + Limit: 50, + EnableUserData: false, + LibrarySeriesId: item.Id + + }).then(function (result) { + + if (result.Items.length) { + page.querySelector('#seriesScheduleSection').classList.remove('hide'); + + } else { + page.querySelector('#seriesScheduleSection').classList.add('hide'); + } + + page.querySelector('#seriesScheduleList').innerHTML = listView.getListViewHtml({ + items: result.Items, + enableUserDataButtons: false, + showParentTitle: false, + image: false, + showProgramDateTime: true, + mediaInfo: false, + showTitle: true, + moreButton: false, + action: 'programdialog' + }); + + Dashboard.hideLoadingMsg(); }); } diff --git a/dashboard-ui/scripts/livetvchannel.js b/dashboard-ui/scripts/livetvchannel.js index 218441cc5..e1f24c1e7 100644 --- a/dashboard-ui/scripts/livetvchannel.js +++ b/dashboard-ui/scripts/livetvchannel.js @@ -55,7 +55,8 @@ SortBy: "StartDate", EnableTotalRecordCount: false, EnableImages: false, - ImageTypeLimit: 0 + ImageTypeLimit: 0, + EnableUserData: false }).then(function (result) { @@ -64,7 +65,7 @@ }); } - window.LiveTvChannelPage = { + return { renderPrograms: loadPrograms };