diff --git a/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js b/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js index 1adecfb0f1..0cdd7d1b1b 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js +++ b/dashboard-ui/bower_components/emby-webcomponents/browserdeviceprofile.js @@ -263,12 +263,14 @@ define(['browser'], function (browser) { // Otherwise with HLS and mp3 audio we're seeing some browsers // safari is lying if ((videoTestElement.canPlayType('audio/mp4; codecs="ac-3"').replace(/no/, '') && !browser.safari) || browser.edgeUwp || browser.tizen) { - videoAudioCodecs.push('ac3'); + if ((options.disableVideoAudioCodecs || []).indexOf('ac3') == -1) { + videoAudioCodecs.push('ac3'); - // This works in edge desktop, but not mobile - // TODO: Retest this on mobile - if (!browser.edge || !browser.touch) { - hlsVideoAudioCodecs.push('ac3'); + // This works in edge desktop, but not mobile + // TODO: Retest this on mobile + if (!browser.edge || !browser.touch) { + hlsVideoAudioCodecs.push('ac3'); + } } } diff --git a/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/cardbuilder.js b/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/cardbuilder.js index ff6d52dfcd..a744d2f9ea 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/cardbuilder.js +++ b/dashboard-ui/bower_components/emby-webcomponents/cardbuilder/cardbuilder.js @@ -1188,7 +1188,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'mediaInfo } if (!imgUrl) { - var defaultName = item.EpisodeTitle ? item.Name : itemHelper.getDisplayName(item); + var defaultName = item.Type == 'Program' ? item.Name : itemHelper.getDisplayName(item); cardImageContainerOpen += '
' + defaultName + '
'; } diff --git a/dashboard-ui/bower_components/emby-webcomponents/indicators/indicators.js b/dashboard-ui/bower_components/emby-webcomponents/indicators/indicators.js index 2534d64dc9..8c52bda358 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/indicators/indicators.js +++ b/dashboard-ui/bower_components/emby-webcomponents/indicators/indicators.js @@ -105,7 +105,7 @@ define(['css!./indicators.css', 'material-icons'], function () { return ''; } } - else if (item.TimerId) { + else if (item.TimerId || item.Type == 'Timer') { return ''; } diff --git a/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.js b/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.js index e02e083a62..53c11559c0 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.js +++ b/dashboard-ui/bower_components/emby-webcomponents/itemhovermenu/itemhovermenu.js @@ -140,13 +140,6 @@ html += ''; buttonCount++; - html += userdataButtons.getIconsHtml({ - item: item, - style: 'fab-mini', - cssClass: 'cardOverlayFab', - iconCssClass: 'cardOverlayFab-md-icon' - }); - html += ''; html += ''; @@ -215,6 +208,16 @@ innerElem.innerHTML = getOverlayHtml(apiClient, item, user, dataElement); + userdataButtons.fill({ + item: item, + style: 'fab-mini', + cssClass: 'cardOverlayFab', + iconCssClass: 'cardOverlayFab-md-icon', + element: innerElem.querySelector('.cardOverlayButtons'), + fillMode: 'insertAdjacent', + insertLocation: 'beforeend' + }); + innerElem.querySelector('.cardOverlayButtons').addEventListener('click', onCardOverlayButtonsClick); }); diff --git a/dashboard-ui/bower_components/emby-webcomponents/userdatabuttons/userdatabuttons.js b/dashboard-ui/bower_components/emby-webcomponents/userdatabuttons/userdatabuttons.js index f8fe0bbc5d..25799389ef 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/userdatabuttons/userdatabuttons.js +++ b/dashboard-ui/bower_components/emby-webcomponents/userdatabuttons/userdatabuttons.js @@ -1,4 +1,11 @@ -define(['connectionManager', 'globalize', 'paper-icon-button-light', 'material-icons', 'emby-button', 'css!./userdatabuttons'], function (connectionManager, globalize) { +define(['connectionManager', 'globalize', 'dom', 'paper-icon-button-light', 'material-icons', 'emby-button', 'css!./userdatabuttons'], function (connectionManager, globalize, dom) { + + var userDataMethods = { + markPlayed: markPlayed, + markDislike: markDislike, + markLike: markLike, + markFavorite: markFavorite + }; function getUserDataButtonHtml(method, itemId, buttonCssClass, iconCssClass, icon, tooltip, style) { @@ -22,16 +29,49 @@ define(['connectionManager', 'globalize', 'paper-icon-button-light', 'material-i iconCssClass += 'md-icon'; - return ''; } + function onContainerClick(e) { + + var btnUserData = dom.parentWithClass(e.target, 'btnUserData'); + + if (!btnUserData) { + return; + } + + var method = btnUserData.getAttribute('data-method'); + userDataMethods[method](btnUserData); + } + function fill(options) { var html = getIconsHtml(options); - options.element.innerHTML = html; + if (options.fillMode == 'insertAdjacent') { + options.element.insertAdjacentHTML(options.insertLocation || 'beforeend', html); + } else { + options.element.innerHTML = html; + } + + dom.removeEventListener(options.element, 'click', onContainerClick, { + passive: true + }); + + dom.addEventListener(options.element, 'click', onContainerClick, { + passive: true + }); + } + + function destroy(options) { + + options.element.innerHTML = ''; + + dom.removeEventListener(options.element, 'click', onContainerClick, { + passive: true + }); } function getIconsHtml(options) { @@ -195,15 +235,9 @@ define(['connectionManager', 'globalize', 'paper-icon-button-light', 'material-i return apiClient.clearUserItemRating(apiClient.getCurrentUserId(), id); } - window.UserDataButtons = { - markPlayed: markPlayed, - markDislike: markDislike, - markLike: markLike, - markFavorite: markFavorite - }; - return { fill: fill, + destroy: destroy, getIconsHtml: getIconsHtml }; diff --git a/dashboard-ui/components/remotecontrol.js b/dashboard-ui/components/remotecontrol.js index eec45adb56..e52cbd51da 100644 --- a/dashboard-ui/components/remotecontrol.js +++ b/dashboard-ui/components/remotecontrol.js @@ -202,14 +202,17 @@ } ApiClient.getItem(Dashboard.getCurrentUserId(), item.Id).then(function (fullItem) { - context.querySelector('.nowPlayingPageUserDataButtons').innerHTML = userdataButtons.getIconsHtml({ + userdataButtons.fill({ item: fullItem, includePlayed: false, - style: 'fab-mini' + style: 'fab-mini', + element: context.querySelector('.nowPlayingPageUserDataButtons') }); }); } else { - context.querySelector('.nowPlayingPageUserDataButtons').innerHTML = ''; + userdataButtons.destroy({ + element: context.querySelector('.nowPlayingPageUserDataButtons') + }); } } diff --git a/dashboard-ui/devices/ios/ios.css b/dashboard-ui/devices/ios/ios.css index 045f5173a4..54bb16a3cb 100644 --- a/dashboard-ui/devices/ios/ios.css +++ b/dashboard-ui/devices/ios/ios.css @@ -28,6 +28,10 @@ body:not(.dashboardDocument) .mainDrawerButton { height: 50px; } +.ui-body-b .libraryViewNav { + box-shadow: none; +} + /*.viewMenuBar, .ui-body-b .libraryViewNav { background: rgba(34,35,38,.90); -webkit-backdrop-filter: blur(5px); diff --git a/dashboard-ui/scripts/connectlogin.js b/dashboard-ui/scripts/connectlogin.js index d1d522c772..ab296670d5 100644 --- a/dashboard-ui/scripts/connectlogin.js +++ b/dashboard-ui/scripts/connectlogin.js @@ -242,10 +242,14 @@ passwordConfirm: page.querySelector('#txtSignupPasswordConfirm', page).value, grecaptcha: greResponse - }).then(function () { + }).then(function (result) { + + var msg = result.Validated ? + Globalize.translate('MessageThankYouForConnectSignUpNoValidation') : + Globalize.translate('MessageThankYouForConnectSignUp'); Dashboard.alert({ - message: Globalize.translate('MessageThankYouForConnectSignUp'), + message: msg, callback: function () { Dashboard.navigate('connectlogin.html?mode=welcome'); } diff --git a/dashboard-ui/scripts/htmlmediarenderer.js b/dashboard-ui/scripts/htmlmediarenderer.js index e6de4ae650..703e1f07d8 100644 --- a/dashboard-ui/scripts/htmlmediarenderer.js +++ b/dashboard-ui/scripts/htmlmediarenderer.js @@ -196,7 +196,7 @@ // For now don't do this in edge because we lose some native audio support if (browser.edge) { - return false; + //return false; } // hls.js is only in beta. needs more testing. diff --git a/dashboard-ui/scripts/itemdetailpage.js b/dashboard-ui/scripts/itemdetailpage.js index e0c3e0a1c2..de305887c2 100644 --- a/dashboard-ui/scripts/itemdetailpage.js +++ b/dashboard-ui/scripts/itemdetailpage.js @@ -1412,13 +1412,13 @@ var userDataIcons = page.querySelectorAll('.userDataIcons'); - var html = userdataButtons.getIconsHtml({ - item: item, - style: 'fab-mini' - }); - for (var i = 0, length = userDataIcons.length; i < length; i++) { - userDataIcons[i].innerHTML = html; + + userdataButtons.fill({ + item: item, + style: 'fab-mini', + element: userDataIcons[i] + }); } } diff --git a/dashboard-ui/scripts/mediaplayer-video.js b/dashboard-ui/scripts/mediaplayer-video.js index 5aada04c30..d1cbbbc2d4 100644 --- a/dashboard-ui/scripts/mediaplayer-video.js +++ b/dashboard-ui/scripts/mediaplayer-video.js @@ -1008,7 +1008,7 @@ // 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.RunTimeTicks && isHls && !browser.edge) { + if (!mediaSource.RunTimeTicks && isHls) { var hlsPlaylistUrl = streamInfo.url.replace('master.m3u8', 'live.m3u8'); diff --git a/dashboard-ui/scripts/mediaplayer.js b/dashboard-ui/scripts/mediaplayer.js index 28d4e232af..cbe5c6e7bf 100644 --- a/dashboard-ui/scripts/mediaplayer.js +++ b/dashboard-ui/scripts/mediaplayer.js @@ -163,11 +163,17 @@ define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appS var playSessionId = getParameterByName('PlaySessionId', currentSrc); var liveStreamId = getParameterByName('LiveStreamId', currentSrc); + var disableVideoAudioCodecs = []; + if (!AppInfo.isNativeApp && !self.currentMediaSource.RunTimeTicks) { + disableVideoAudioCodecs.push('ac3'); + } + Dashboard.getDeviceProfile(null, { enableMkvProgressive: self.currentMediaSource.RunTimeTicks != null, enableTsProgressive: self.currentMediaSource.RunTimeTicks != null, - enableHls: !browserInfo.firefox || self.currentMediaSource.RunTimeTicks == null + enableHls: !browserInfo.firefox || self.currentMediaSource.RunTimeTicks == null, + disableVideoAudioCodecs: disableVideoAudioCodecs }).then(function (deviceProfile) { @@ -677,10 +683,17 @@ define(['appSettings', 'userSettings', 'appStorage', 'datetime'], function (appS var onBitrateDetected = function () { + var disableVideoAudioCodecs = []; + + if (!AppInfo.isNativeApp && !item.RunTimeTicks) { + disableVideoAudioCodecs.push('ac3'); + } + Dashboard.getDeviceProfile(null, { enableMkvProgressive: item.RunTimeTicks != null, - enableTsProgressive: item.RunTimeTicks != null + enableTsProgressive: item.RunTimeTicks != null, + disableVideoAudioCodecs: disableVideoAudioCodecs }).then(function (deviceProfile) { playOnDeviceProfileCreated(deviceProfile, item, startPosition, callback); diff --git a/dashboard-ui/scripts/nowplayingbar.js b/dashboard-ui/scripts/nowplayingbar.js index b18b7e1911..7f169dd367 100644 --- a/dashboard-ui/scripts/nowplayingbar.js +++ b/dashboard-ui/scripts/nowplayingbar.js @@ -596,13 +596,16 @@ if (nowPlayingItem.Id) { ApiClient.getItem(Dashboard.getCurrentUserId(), nowPlayingItem.Id).then(function (item) { - nowPlayingUserData.innerHTML = userdataButtons.getIconsHtml({ + userdataButtons.fill({ item: item, - includePlayed: false + includePlayed: false, + element: nowPlayingUserData }); }); } else { - nowPlayingUserData.innerHTML = ''; + userdataButtons.destroy({ + element: nowPlayingUserData + }); } } diff --git a/dashboard-ui/strings/en-US.json b/dashboard-ui/strings/en-US.json index 5b5c16073e..2cc53f46fa 100644 --- a/dashboard-ui/strings/en-US.json +++ b/dashboard-ui/strings/en-US.json @@ -1965,6 +1965,7 @@ "ErrorMessageUsernameInUse": "The username is already in use. Please choose a new name and try again.", "ErrorMessageEmailInUse": "The email address is already in use. Please enter a new email address and try again, or use the forgot password feature.", "MessageThankYouForConnectSignUp": "Thank you for signing up for Emby Connect. An email will be sent to your address with instructions on how to confirm your new account. Please confirm the account and then return here to sign in.", + "MessageThankYouForConnectSignUpNoValidation": "Thank you for signing up for Emby Connect! You will now be asked to login with your Emby Connect information.", "ButtonShare": "Share", "HeaderConfirm": "Confirm", "MessageConfirmDeleteTunerDevice": "Are you sure you wish to delete this device?", @@ -2139,5 +2140,6 @@ "LabelConvertRecordingsTo": "Convert recordings to:", "HeaderUpcomingOnTV": "Upcoming On TV", "LabelOptionalNetworkPath": "(Optional) Shared network folder:", - "LabelOptionalNetworkPathHelp": "If this folder is shared on your network, supplying the network share path can allow Emby apps on other devices to access media files directly." + "LabelOptionalNetworkPathHelp": "If this folder is shared on your network, supplying the network share path can allow Emby apps on other devices to access media files directly.", + "ButtonPlayExternalPlayer": "Play with external player" }