diff --git a/dashboard-ui/addplugin.html b/dashboard-ui/addplugin.html index 5ed6f4a31f..089c23096d 100644 --- a/dashboard-ui/addplugin.html +++ b/dashboard-ui/addplugin.html @@ -1,4 +1,4 @@ -
+
@@ -9,25 +9,26 @@
-

+

-
-

${HeaderInstall}

+
+

${HeaderInstall}

-

- - -

+
+ +

- +

@@ -75,28 +76,29 @@
- +
-
-

${HeaderReviews}

-
+
+

-
-

${HeaderDeveloperInfo}

-

- +
+
-
-

${HeaderRevisionHistory}

-
+
+
+
+
diff --git a/dashboard-ui/bower_components/emby-webcomponents/.bower.json b/dashboard-ui/bower_components/emby-webcomponents/.bower.json index 79419a1a0b..e757b139c8 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/.bower.json +++ b/dashboard-ui/bower_components/emby-webcomponents/.bower.json @@ -15,12 +15,12 @@ }, "devDependencies": {}, "ignore": [], - "version": "1.4.63", - "_release": "1.4.63", + "version": "1.4.69", + "_release": "1.4.69", "_resolution": { "type": "version", - "tag": "1.4.63", - "commit": "c557118405664924ccb91634f8dcf9aa2667bcb1" + "tag": "1.4.69", + "commit": "24a5ea44282dc2e0a537c6245aedd88877ebb9ad" }, "_source": "https://github.com/MediaBrowser/emby-webcomponents.git", "_target": "^1.2.0", diff --git a/dashboard-ui/bower_components/emby-webcomponents/alphapicker/alphapicker.js b/dashboard-ui/bower_components/emby-webcomponents/alphapicker/alphapicker.js index 8f790d7a77..db53a6583a 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/alphapicker/alphapicker.js +++ b/dashboard-ui/bower_components/emby-webcomponents/alphapicker/alphapicker.js @@ -24,8 +24,9 @@ define(['focusManager', 'css!./style.css', 'clearButtonStyle', 'paper-icon-butto html += '
'; if (options.mode == 'keyboard') { + // space_bar icon html += ''; } else { letters = ['#']; @@ -36,8 +37,9 @@ define(['focusManager', 'css!./style.css', 'clearButtonStyle', 'paper-icon-butto html += letters.map(getLetterButton).join(''); if (options.mode == 'keyboard') { + // backspace icon html += ''; html += '
'; diff --git a/dashboard-ui/bower_components/emby-webcomponents/browser.js b/dashboard-ui/bower_components/emby-webcomponents/browser.js index 476da407a0..bb64e7b349 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/browser.js +++ b/dashboard-ui/bower_components/emby-webcomponents/browser.js @@ -28,6 +28,40 @@ return false; } + function isStyleSupported(prop, value) { + // If no value is supplied, use "inherit" + value = arguments.length === 2 ? value : 'inherit'; + // Try the native standard method first + if ('CSS' in window && 'supports' in window.CSS) { + return window.CSS.supports(prop, value); + } + // Check Opera's native method + if ('supportsCSS' in window) { + return window.supportsCSS(prop, value); + } + + // need try/catch because it's failing on tizen + + try { + // Convert to camel-case for DOM interactions + var camel = prop.replace(/-([a-z]|[0-9])/ig, function (all, letter) { + return (letter + '').toUpperCase(); + }); + // Check if the property is supported + var support = (camel in el.style); + // Create test element + var el = document.createElement('div'); + // Assign the property and value to invoke + // the CSS interpreter + el.style.cssText = prop + ':' + value; + // Ensure both the property and value are + // supported and return + return support && (el.style[camel] !== ''); + } catch (err) { + return false; + } + } + var uaMatch = function (ua) { ua = ua.toLowerCase(); @@ -106,7 +140,11 @@ browser.tv = isTv(); browser.operaTv = browser.tv && userAgent.toLowerCase().indexOf('opr/') != -1; - browser.noFlex = (browser.tv && !browser.chrome && !browser.operaTv) || browser.ps4; + if (!isStyleSupported('display', 'flex')) { + browser.noFlex = true; + } + + //browser.noFlex = (browser.tv && !browser.chrome && !browser.operaTv) || browser.ps4; return browser; }); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/dialoghelper/dialoghelper.css b/dashboard-ui/bower_components/emby-webcomponents/dialoghelper/dialoghelper.css index e2e982b3d6..6ad6be829a 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/dialoghelper/dialoghelper.css +++ b/dashboard-ui/bower_components/emby-webcomponents/dialoghelper/dialoghelper.css @@ -71,7 +71,7 @@ .dialog .buttons { position: relative; - padding: 8px 8px 0 24px; + padding: 8px 8px 8px 24px; margin: 0; color: #3f51b5; display: -ms-flexbox; diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.css b/dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.css index ccbb2325f4..12be938ee0 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.css +++ b/dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.css @@ -153,11 +153,13 @@ _:-ms-input-placeholder, :root .mdl-slider.mdl-slider { } .layout-tv .mdl-slider::-webkit-slider-thumb { - display: none; + width: 0; + height: 0; } .layout-tv .mdl-slider:hover::-webkit-slider-thumb { - display: block; + width: 16px; + height: 16px; } .mdl-slider.is-lowest-value::-webkit-slider-thumb { diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.js b/dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.js index 20a21c28ca..7e1ef758cb 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.js +++ b/dashboard-ui/bower_components/emby-webcomponents/emby-slider/emby-slider.js @@ -22,18 +22,20 @@ // range.classList.remove('is-lowest-value'); //} - if (backgroundLower) { - var fraction = (range.value - range.min) / (range.max - range.min); + var value = range.value; + requestAnimationFrame(function () { - backgroundLower.style.flex = fraction; - backgroundLower.style.webkitFlex = fraction; - backgroundUpper.style.flex = 1 - fraction; - backgroundUpper.style.webkitFlex = 1 - fraction; - } + if (backgroundLower) { + var fraction = (value - range.min) / (range.max - range.min); + + backgroundLower.style.flex = fraction; + backgroundUpper.style.flex = 1 - fraction; + } + }); } function updateBubble(range, bubble) { - + var value = range.value; bubble.style.left = (value - 1) + '%'; @@ -71,15 +73,22 @@ var backgroundUpper = containerElement.querySelector('.mdl-slider__background-upper'); var sliderBubble = containerElement.querySelector('.sliderBubble'); + var hasHideClass = sliderBubble.classList.contains('hide'); + this.addEventListener('input', function (e) { this.dragging = true; updateBubble(this, sliderBubble); - sliderBubble.classList.remove('hide'); + + if (hasHideClass) { + sliderBubble.classList.remove('hide'); + hasHideClass = false; + } }); this.addEventListener('change', function () { this.dragging = false; updateValues(this, backgroundLower, backgroundUpper); sliderBubble.classList.add('hide'); + hasHideClass = true; }); if (!supportsNativeProgressStyle) { diff --git a/dashboard-ui/bower_components/emby-webcomponents/inputmanager.js b/dashboard-ui/bower_components/emby-webcomponents/inputmanager.js new file mode 100644 index 0000000000..d1b4b2b2a7 --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/inputmanager.js @@ -0,0 +1,242 @@ +define(['playbackManager', 'focusManager', 'embyRouter'], function (playbackManager, focusManager, embyRouter) { + + var lastInputTime = new Date().getTime(); + + function notify() { + lastInputTime = new Date().getTime(); + } + + function idleTime() { + return new Date().getTime() - lastInputTime; + } + + function select(sourceElement) { + + sourceElement.click(); + } + + var eventListenerCount = 0; + function on(scope, fn) { + eventListenerCount++; + scope.addEventListener('command', fn); + } + + function off(scope, fn) { + + if (eventListenerCount) { + eventListenerCount--; + } + + scope.removeEventListener('command', fn); + } + + var commandTimes = {}; + + function checkCommandTime(command) { + + var last = commandTimes[command] || 0; + var now = new Date().getTime(); + + if ((now - last) < 1000) { + return false; + } + + commandTimes[command] = now; + return true; + } + + function handleCommand(name, options) { + + notify(); + + var sourceElement = (options ? options.sourceElement : null); + + if (sourceElement) { + sourceElement = focusManager.focusableParent(sourceElement); + } + + sourceElement = sourceElement || document.activeElement || window; + + if (eventListenerCount) { + var customEvent = new CustomEvent("command", { + detail: { + command: name + }, + bubbles: true, + cancelable: true + }); + + var eventResult = sourceElement.dispatchEvent(customEvent); + if (!eventResult) { + // event cancelled + return; + } + } + + switch (name) { + + case 'up': + focusManager.moveUp(sourceElement); + break; + case 'down': + focusManager.moveDown(sourceElement); + break; + case 'left': + focusManager.moveLeft(sourceElement); + break; + case 'right': + focusManager.moveRight(sourceElement); + break; + case 'home': + embyRouter.goHome(); + break; + case 'settings': + embyRouter.showSettings(); + break; + case 'back': + embyRouter.back(); + break; + case 'forward': + // TODO + break; + case 'select': + select(sourceElement); + break; + case 'pageup': + // TODO + break; + case 'pagedown': + // TODO + break; + case 'end': + // TODO + break; + case 'menu': + case 'info': + // TODO + break; + case 'next': + if (playbackManager.isPlayingVideo()) { + playbackManager.nextChapter(); + } else if (playbackManager.isPlaying()) { + playbackManager.nextTrack(); + } + break; + case 'previous': + + if (playbackManager.isPlayingVideo()) { + playbackManager.previousChapter(); + } else if (playbackManager.isPlaying()) { + playbackManager.previousTrack(); + } + break; + case 'guide': + embyRouter.showGuide(); + break; + case 'recordedtv': + embyRouter.showRecordedTV(); + break; + case 'record': + // TODO + break; + case 'livetv': + embyRouter.showLiveTV(); + break; + case 'mute': + playbackManager.mute(); + break; + case 'unmute': + playbackManager.unMute(); + break; + case 'togglemute': + playbackManager.toggleMute(); + break; + case 'volumedown': + playbackManager.volumeDown(); + break; + case 'volumeup': + playbackManager.volumeUp(); + break; + case 'play': + playbackManager.unpause(); + break; + case 'pause': + playbackManager.pause(); + break; + case 'playpause': + playbackManager.playPause(); + break; + case 'stop': + if (checkCommandTime('stop')) { + playbackManager.stop(); + } + break; + case 'changezoom': + // TODO + break; + case 'changeaudiotrack': + // TODO + break; + case 'changesubtitletrack': + break; + case 'search': + embyRouter.showSearch(); + break; + case 'favorites': + embyRouter.showFavorites(); + break; + case 'fastforward': + playbackManager.fastForward(); + break; + case 'rewind': + playbackManager.rewind(); + break; + case 'togglefullscreen': + // TODO + break; + case 'disabledisplaymirror': + playbackManager.enableDisplayMirroring(false); + break; + case 'enabledisplaymirror': + playbackManager.enableDisplayMirroring(true); + break; + case 'toggledisplaymirror': + playbackManager.toggleDisplayMirroring(); + break; + case 'movies': + // TODO + break; + case 'music': + // TODO + break; + case 'tv': + // TODO + break; + case 'latestepisodes': + // TODO + break; + case 'nowplaying': + // TODO + break; + case 'upcomingtv': + // TODO + break; + case 'nextup': + // TODO + break; + default: + break; + } + } + + document.addEventListener('click', notify); + + return { + trigger: handleCommand, + handle: handleCommand, + notify: notify, + idleTime: idleTime, + on: on, + off: off + }; +}); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.css b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.css index 20d11ca02f..4b6d505654 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/listview/listview.css +++ b/dashboard-ui/bower_components/emby-webcomponents/listview/listview.css @@ -11,7 +11,7 @@ button.listItem { } .listItem { - display: flex; + display: block; align-items: center; text-align: left; padding: 0 1em !important; @@ -26,12 +26,16 @@ button.listItem { flex-shrink: 0; } + .listItem > * { + display: inline-block; + vertical-align: middle; + } + .listItemBody { flex-grow: 1; padding: 0 1.15em; overflow: hidden; text-overflow: ellipsis; - display: flex; flex-direction: column; vertical-align: middle; justify-content: center; @@ -128,3 +132,11 @@ button.listItem { box-shadow: none !important; background-color: transparent !important; } + + +@supports (display: flex) { + + .listItem, .listItemBody { + display: flex; + } +} diff --git a/dashboard-ui/bower_components/emby-webcomponents/router.js b/dashboard-ui/bower_components/emby-webcomponents/router.js index dfee07d3dc..78c235c773 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/router.js +++ b/dashboard-ui/bower_components/emby-webcomponents/router.js @@ -19,11 +19,20 @@ define(['loading', 'viewManager', 'skinManager', 'pluginManager', 'backdrop', 'b showSearch: function () { skinManager.getCurrentSkin().search(); }, + showGenre: function (options) { + skinManager.getCurrentSkin().showGenre(options); + }, showGuide: function () { skinManager.getCurrentSkin().showGuide(); }, showLiveTV: function () { skinManager.getCurrentSkin().showLiveTV(); + }, + showRecordedTV: function () { + skinManager.getCurrentSkin().showRecordedTV(); + }, + showFavorites: function () { + skinManager.getCurrentSkin().showFavorites(); } }; diff --git a/dashboard-ui/bower_components/emby-webcomponents/slideshow/slideshow.js b/dashboard-ui/bower_components/emby-webcomponents/slideshow/slideshow.js index cd89096aab..c42a776ad7 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/slideshow/slideshow.js +++ b/dashboard-ui/bower_components/emby-webcomponents/slideshow/slideshow.js @@ -21,26 +21,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f options.tag = item.AlbumPrimaryImageTag; return apiClient.getScaledImageUrl(item.AlbumId, options); } - - //else if (item.AlbumId && item.SeriesPrimaryImageTag) { - - // imgUrl = ApiClient.getScaledImageUrl(item.SeriesId, { - // type: "Primary", - // width: downloadWidth, - // tag: item.SeriesPrimaryImageTag, - // minScale: minScale - // }); - - //} - //else if (item.ParentPrimaryImageTag) { - - // imgUrl = ApiClient.getImageUrl(item.ParentPrimaryImageItemId, { - // type: "Primary", - // width: downloadWidth, - // tag: item.ParentPrimaryImageTag, - // minScale: minScale - // }); - //} } return null; diff --git a/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json b/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json index 5d4ee9e1c5..5d410526e3 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json +++ b/dashboard-ui/bower_components/emby-webcomponents/strings/en-US.json @@ -86,5 +86,11 @@ "ReplaceAllMetadata": "Replace all metadata", "SearchForMissingMetadata": "Search for missing metadata", "LabelRefreshMode": "Refresh mode:", + "NoItemsFound": "No items found.", + "HeaderSaySomethingLike": "Say Something Like...", + "ButtonTryAgain": "Try Again", + "HeaderYouSaid": "You Said...", + "MessageWeDidntRecognizeCommand": "We're sorry, we didn't recognize that command.", + "MessageIfYouBlockedVoice": "If you denied voice access to the app you'll need to reconfigure before trying again.", "RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Emby Server dashboard." } \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewmanager.js b/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewmanager.js index 0dcd7f9b6c..c47efcc62d 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewmanager.js +++ b/dashboard-ui/bower_components/emby-webcomponents/viewmanager/viewmanager.js @@ -1,4 +1,4 @@ -define(['viewcontainer', 'focusManager', 'queryString', 'connectionManager', 'events'], function (viewcontainer, focusManager, queryString, connectionManager, events) { +define(['viewcontainer', 'focusManager', 'queryString', 'layoutManager'], function (viewcontainer, focusManager, queryString, layoutManager) { var currentView; var dispatchPageEvents; @@ -51,7 +51,7 @@ define(['viewcontainer', 'focusManager', 'queryString', 'connectionManager', 'ev focusManager.autoFocus(view); } } - else { + else if (!layoutManager.mobile) { if (view.activeElement && document.body.contains(view.activeElement) && focusManager.isCurrentlyFocusable(view.activeElement)) { focusManager.focus(view.activeElement); } else { diff --git a/dashboard-ui/voice/Readme.md b/dashboard-ui/bower_components/emby-webcomponents/voice/Readme.md similarity index 100% rename from dashboard-ui/voice/Readme.md rename to dashboard-ui/bower_components/emby-webcomponents/voice/Readme.md diff --git a/dashboard-ui/bower_components/emby-webcomponents/voice/commands/controlcommands.js b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/controlcommands.js new file mode 100644 index 0000000000..c1b46cc0e7 --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/controlcommands.js @@ -0,0 +1,10 @@ +define(['playbackManager'], function (playbackManager) { + + return function (result) { + result.success = true; + if (result.properties.devicename) { + playbackManager.trySetActiveDeviceName(result.properties.devicename); + } + return; + } +}); \ No newline at end of file diff --git a/dashboard-ui/voice/commands/disablecommands.js b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/disablecommands.js similarity index 61% rename from dashboard-ui/voice/commands/disablecommands.js rename to dashboard-ui/bower_components/emby-webcomponents/voice/commands/disablecommands.js index 6338fecd5f..20f1e004f6 100644 --- a/dashboard-ui/voice/commands/disablecommands.js +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/disablecommands.js @@ -1,11 +1,10 @@ - -define([], function () { +define(['inputManager'], function (inputManager) { - return function (result) { + return function (result) { result.success = true; switch (result.item.deviceid) { case 'displaymirroring': - MediaController.enableDisplayMirroring(false); + inputManager.trigger('disabledisplaymirror'); break; default: result.success = false; diff --git a/dashboard-ui/voice/commands/enablecommands.js b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/enablecommands.js similarity index 69% rename from dashboard-ui/voice/commands/enablecommands.js rename to dashboard-ui/bower_components/emby-webcomponents/voice/commands/enablecommands.js index e790731f48..af88c8e432 100644 --- a/dashboard-ui/voice/commands/enablecommands.js +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/enablecommands.js @@ -1,11 +1,10 @@ - -define([], function () { +define(['inputManager'], function (inputManager) { return function (result) { result.success = true; switch (result.item.deviceid) { case 'displaymirroring': - MediaController.enableDisplayMirroring(true); + inputManager.trigger('enabledisplaymirror'); break; default: result.success = false; diff --git a/dashboard-ui/voice/commands/playcommands.js b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/playcommands.js similarity index 85% rename from dashboard-ui/voice/commands/playcommands.js rename to dashboard-ui/bower_components/emby-webcomponents/voice/commands/playcommands.js index ce2b500fde..7aedf49c6f 100644 --- a/dashboard-ui/voice/commands/playcommands.js +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/playcommands.js @@ -1,5 +1,4 @@ - -define([], function () { +define(['connectionManager', 'playbackManager', 'globalize'], function (connectionManager, playbackManager, globalize) { /// Play items. /// The items. @@ -16,13 +15,13 @@ define([], function () { }); if (items.length) { - MediaController.play({ + playbackManager.play({ ids: items }); } else { require(['toast'], function (toast) { - toast(Globalize.translate('MessageNoItemsFound')); + toast(globalize.translate('sharedcomponents#NoItemsFound')); }); } } @@ -63,9 +62,10 @@ define([], function () { query.IncludeItemTypes = result.item.itemType; } + var apiClient = connectionManager.currentApiClient(); if (result.item.sourceid === 'nextup') { - ApiClient.getNextUpEpisodes(query).then(function (queryResult) { + apiClient.getNextUpEpisodes(query).then(function (queryResult) { playItems(queryResult.Items, result.item.shuffle); @@ -93,7 +93,7 @@ define([], function () { } - ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (queryResult) { + apiClient.getItems(apiClient.getCurrentUserId(), query).then(function (queryResult) { playItems(queryResult.Items, result.item.shuffle); }); diff --git a/dashboard-ui/bower_components/emby-webcomponents/voice/commands/searchcommands.js b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/searchcommands.js new file mode 100644 index 0000000000..715114f9ca --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/searchcommands.js @@ -0,0 +1,11 @@ +define(['inputManager'], function (inputManager) { + + return function (result) { + switch (result.item.deviceid) { + default: + result.success = false; + return; + } + } + +}); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/voice/commands/showcommands.js b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/showcommands.js new file mode 100644 index 0000000000..4446af9b53 --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/showcommands.js @@ -0,0 +1,98 @@ +define(['inputManager', 'connectionManager', 'embyRouter'], function (inputManager, connectionManager, embyRouter) { + + return function (result) { + result.success = true; + switch (result.item.sourceid) { + case 'music': + inputManager.trigger('music'); + break; + case 'movies': + if (result.properties.movieName) { + + //TODO: Find a way to display movie + var query = { + Limit: 1, + UserId: result.userId, + ExcludeLocationTypes: "Virtual", + NameStartsWith: result.item.itemType + }; + + if (result.item.itemType) { + query.IncludeItemTypes = result.item.itemType; + } + + var apiClient = connectionManager.currentApiClient(); + apiClient.getItems(apiClient.getCurrentUserId(), query).then(function (queryResult) { + + if (queryResult.Items.length) { + embyRouter.showItem(queryResult.Items[0]); + } + }); + + } else { + inputManager.trigger('movies'); + } + + break; + case 'tvseries': + inputManager.trigger('tv'); + break; + case 'livetv': + var act = result.item.menuid; + if (act) { + if (act.indexOf('livetv') != -1) { + inputManager.trigger('livetv'); + } else if (act.indexOf('guide') != -1) { + inputManager.trigger('guide'); + } else if (act.indexOf('channels') != -1) { + inputManager.trigger('livetv'); + } else if (act.indexOf('recordings') != -1) { + inputManager.trigger('recordedtv'); + } else if (act.indexOf('scheduled') != -1) { + inputManager.trigger('recordedtv'); + } else if (act.indexOf('series') != -1) { + inputManager.trigger('recordedtv'); + } else { + inputManager.trigger('livetv'); + } + } else { + inputManager.trigger('livetv'); + } + break; + case 'recordings': + inputManager.trigger('recordedtv'); + break; + case 'latestepisodes': + inputManager.trigger('latestepisodes'); + case 'home': + var act = result.item.menuid; + if (act) { + if (act.indexOf('home') != -1) { + inputManager.trigger('home'); + } + else if (act.indexOf('nextup') != -1) { + inputManager.trigger('nextup'); + } + else if (act.indexOf('favorites') != -1) { + inputManager.trigger('favorites'); + } else if (act.indexOf('upcoming') != -1) { + inputManager.trigger('upcomingtv'); + } + else if (act.indexOf('nowplaying') != -1) { + inputManager.trigger('nowplaying'); + } + else { + inputManager.trigger('home'); + } + } else { + inputManager.trigger('home'); + } + case 'group': + break; + default: + result.success = false; + return; + } + + } +}); \ No newline at end of file diff --git a/dashboard-ui/voice/commands/togglecommands.js b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/togglecommands.js similarity index 69% rename from dashboard-ui/voice/commands/togglecommands.js rename to dashboard-ui/bower_components/emby-webcomponents/voice/commands/togglecommands.js index 526668229c..9fa7382bd0 100644 --- a/dashboard-ui/voice/commands/togglecommands.js +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/commands/togglecommands.js @@ -1,16 +1,14 @@ - -define([], function () { +define(['inputManager'], function (inputManager) { return function (result) { result.success = true; switch (result.item.deviceid) { case 'displaymirroring': - MediaController.toggleDisplayMirroring(); + inputManager.trigger('toggledisplaymirror'); break; default: result.success = false; return; } } - }); \ No newline at end of file diff --git a/dashboard-ui/voice/grammar/en-US.json b/dashboard-ui/bower_components/emby-webcomponents/voice/grammar/en-US.json similarity index 99% rename from dashboard-ui/voice/grammar/en-US.json rename to dashboard-ui/bower_components/emby-webcomponents/voice/grammar/en-US.json index 7c3e4f07e9..5c79188a01 100644 --- a/dashboard-ui/voice/grammar/en-US.json +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/grammar/en-US.json @@ -139,7 +139,7 @@ "commandtemplates": [ "Play music", "Play my music", - "Listen to my music " + "Listen to my music" ] }, { @@ -188,7 +188,7 @@ "commandtemplates": [ "Play music", "Play my music", - "Listen to my music " + "Listen to my music" ] }, { @@ -200,7 +200,7 @@ "commandtemplates": [ "Play music", "Play my music", - "Listen to my music ", + "Listen to my music", "shuffle my favorite songs" ] } diff --git a/dashboard-ui/voice/grammar/grammar.json b/dashboard-ui/bower_components/emby-webcomponents/voice/grammar/grammar.json similarity index 100% rename from dashboard-ui/voice/grammar/grammar.json rename to dashboard-ui/bower_components/emby-webcomponents/voice/grammar/grammar.json diff --git a/dashboard-ui/voice/grammarprocessor.js b/dashboard-ui/bower_components/emby-webcomponents/voice/grammarprocessor.js similarity index 100% rename from dashboard-ui/voice/grammarprocessor.js rename to dashboard-ui/bower_components/emby-webcomponents/voice/grammarprocessor.js diff --git a/dashboard-ui/voice/voice.css b/dashboard-ui/bower_components/emby-webcomponents/voice/voice.css similarity index 91% rename from dashboard-ui/voice/voice.css rename to dashboard-ui/bower_components/emby-webcomponents/voice/voice.css index 307b3e0036..a155574a86 100644 --- a/dashboard-ui/voice/voice.css +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/voice.css @@ -1,5 +1,5 @@ .voiceHelpContent { - max-width: 600px; + max-width: 700px; margin: auto; } diff --git a/dashboard-ui/voice/voicecommands.js b/dashboard-ui/bower_components/emby-webcomponents/voice/voicecommands.js similarity index 56% rename from dashboard-ui/voice/voicecommands.js rename to dashboard-ui/bower_components/emby-webcomponents/voice/voicecommands.js index 26f25c4b40..0463cdf6e1 100644 --- a/dashboard-ui/voice/voicecommands.js +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/voicecommands.js @@ -1,6 +1,6 @@ // 09.10.2015 // voicecommands class -define([], function () { +define(['require'], function (require) { /// Process the command. /// Full pathname of the command file. @@ -28,28 +28,28 @@ define([], function () { switch (result.item.actionid) { case 'show': - processCommand('voice/commands/showcommands.js', result).then(function (result) { resolve(result); }); + processCommand('./commands/showcommands.js', result).then(function (result) { resolve(result); }); break; case 'play': - processCommand('voice/commands/playcommands.js', result).then(function (result) { resolve(result); }); + processCommand('./commands/playcommands.js', result).then(function (result) { resolve(result); }); break; case 'shuffle': - processCommand('voice/commands/playcommands.js', result).then(function (result) { resolve(result); }); + processCommand('./commands/playcommands.js', result).then(function (result) { resolve(result); }); break; case 'search': - processCommand('voice/commands/searchcommands.js', result).then(function (result) { resolve(result); }); + processCommand('./commands/searchcommands.js', result).then(function (result) { resolve(result); }); break; case 'control': - processCommand('voice/commands/controlcommands.js', result).then(function (result) { resolve(result); }); + processCommand('./commands/controlcommands.js', result).then(function (result) { resolve(result); }); break; case 'enable': - processCommand('voice/commands/enablecommands.js', result).then(function (result) { resolve(result); }); + processCommand('./commands/enablecommands.js', result).then(function (result) { resolve(result); }); break; case 'disable': - processCommand('voice/commands/disablecommands.js', result).then(function (result) { resolve(result); }); + processCommand('./commands/disablecommands.js', result).then(function (result) { resolve(result); }); break; case 'toggle': - processCommand('voice/commands/togglecommands.js', result).then(function (result) { resolve(result); }); + processCommand('./commands/togglecommands.js', result).then(function (result) { resolve(result); }); break; default: reject(); diff --git a/dashboard-ui/bower_components/emby-webcomponents/voice/voicedialog.js b/dashboard-ui/bower_components/emby-webcomponents/voice/voicedialog.js new file mode 100644 index 0000000000..a7347339bc --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/voicedialog.js @@ -0,0 +1,272 @@ +define(['dialogHelper', './voicereceiver', './voiceprocessor', 'globalize', 'emby-button', 'css!./voice.css', 'material-icons', 'css!./../formdialog'], function (dialogHelper, voicereceiver, voiceprocessor, globalize) { + + var lang = 'en-US'; + + /// Shuffle array. + /// The array. + /// array + function shuffleArray(array) { + var currentIndex = array.length, temporaryValue, randomIndex; + + // While there remain elements to shuffle... + while (0 !== currentIndex) { + + // Pick a remaining element... + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + + // And swap it with the current element. + temporaryValue = array[currentIndex]; + array[currentIndex] = array[randomIndex]; + array[randomIndex] = temporaryValue; + } + + return array; + } + + /// Gets sample commands. + /// The sample commands. + function getSampleCommands(groupid) { + + return voiceprocessor.getCommandGroups().then(function (commandGroups) { + groupid = typeof (groupid) !== 'undefined' ? groupid : ''; + + var commands = []; + commandGroups.map(function (group) { + if ((group.items && group.items.length > 0) && (groupid == group.groupid || groupid == '')) { + + group.items.map(function (item) { + + if (item.commandtemplates && item.commandtemplates.length > 0) { + + item.commandtemplates.map(function (templates) { + commands.push(templates); + }); + } + + }); + } + }); + + return shuffleArray(commands); + }); + } + + /// Gets command group. + /// The groupid. + /// The command group. + function getCommandGroup(groupid) { + return voicereceiver.getCommandGroups() + .then(function (commandgroups) { + if (commandgroups) { + var idx = -1; + + idx = commandgroups.map(function (e) { return e.groupid; }).indexOf(groupid); + + if (idx > -1) + return commandgroups[idx]; + else + return null; + } else + return null; + }); + } + + /// Renders the sample commands. + /// The element. + /// The commands. + /// . + function renderSampleCommands(elem, commands) { + + commands.length = Math.min(commands.length, 4); + + commands = commands.map(function (c) { + + return '
"' + c + '"
'; + + }).join(''); + + elem.querySelector('.exampleCommands').innerHTML = commands; + } + + var currentDialog; + /// Shows the voice help. + /// . + function showVoiceHelp(groupid, title) { + + console.log("Showing Voice Help", groupid, title); + + var isNewDialog = false; + var dlg; + + if (!currentDialog) { + + isNewDialog = true; + + dlg = dialogHelper.createDialog({ + size: 'medium', + removeOnClose: true + }); + + dlg.classList.add('ui-body-b'); + dlg.classList.add('background-theme-b'); + + var html = ''; + html += '
'; + html += ''; + html += '
'; + html += '
'; + html += '
'; + + html += '
'; + + html += '
'; + html += '
'; + html += '
'; + + html += '
'; + + html += '

' + globalize.translate('sharedcomponents#HeaderSaySomethingLike') + '

'; + + html += '
'; + html += '
'; + + // defaultVoiceHelp + html += '
'; + + html += '
'; + html += '

' + globalize.translate('sharedcomponents#HeaderYouSaid') + '

'; + html += + '

'; + html += '

' + globalize.translate('sharedcomponents#MessageWeDidntRecognizeCommand') + '

'; + + html += '
'; + html += ''; + html += '

' + + globalize.translate('sharedcomponents#MessageIfYouBlockedVoice') + + '

'; + + html += '
'; + + html += + ''; + + html += '
'; + html += '
'; + html += '
'; + + html += '
'; + + dlg.innerHTML = html; + document.body.appendChild(dlg); + + dialogHelper.open(dlg); + currentDialog = dlg; + + dlg.addEventListener('close', function () { + currentDialog = null; + }); + + function onCancelClick() { + voicereceiver.cancel(); + dialogHelper.close(dlg); + } + + var closeButtons = dlg.querySelectorAll('.btnCancelVoiceInput'); + for (var i = 0, length = closeButtons.length; i < length; i++) { + closeButtons[i].addEventListener('click', onCancelClick); + } + + dlg.querySelector('.btnRetry').addEventListener('click', function () { + dlg.querySelector('.unrecognizedCommand').classList.add('hide'); + dlg.querySelector('.defaultVoiceHelp').classList.remove('hide'); + listen(); + }); + } + + dlg = currentDialog; + + if (groupid) { + getCommandGroup(groupid) + .then( + function (grp) { + dlg.querySelector('#voiceDialogGroupName').innerText = ' ' + grp.name; + }); + + + getSampleCommands(groupid) + .then(function (commands) { + renderSampleCommands(currentDialog, commands); + listen(); + }) + .catch(function (e) { console.log("Error", e); }); + } else if (isNewDialog) { + getSampleCommands() + .then(function (commands) { + renderSampleCommands(currentDialog, commands); + }); + + } + } + function processInput(input) { + return voiceprocessor.processTranscript(input); + } + + /// Shows the unrecognized command help. + /// . + function showUnrecognizedCommandHelp(command) { + //speak("I don't understend this command"); + if (command) + currentDialog.querySelector('.voiceInputText').innerText = command; + currentDialog.querySelector('.unrecognizedCommand').classList.remove('hide'); + currentDialog.querySelector('.defaultVoiceHelp').classList.add('hide'); + } + + /// Shows the commands. + /// The create user interface. + /// . + function showCommands(result) { + //speak('Hello, what can I do for you?'); + if (result) + showVoiceHelp(result.groupid, result.name); + else + showVoiceHelp(); + } + + function resetDialog() { + if (currentDialog) { + currentDialog.querySelector('.unrecognizedCommand').classList.add('hide'); + currentDialog.querySelector('.defaultVoiceHelp').classList.remove('hide'); + } + } + function showDialog() { + resetDialog(); + showCommands(); + listen(); + } + function listen() { + voicereceiver.listenForCommand(lang || "en-US").then(processInput).then(function (data) { + + closeDialog(); + + }, function (result) { + if (result.error == 'group') { + showVoiceHelp(result.item.groupid, result.groupName); + return; + } + showUnrecognizedCommandHelp(result.text || ''); + }); + } + function closeDialog() { + dialogHelper.close(currentDialog); + voicereceiver.cancel(); + } + + /// An enum constant representing the window. voice input manager option. + return { + showDialog: showDialog + }; + +}); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/voice/voiceprocessor.js b/dashboard-ui/bower_components/emby-webcomponents/voice/voiceprocessor.js new file mode 100644 index 0000000000..d193937b92 --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/voiceprocessor.js @@ -0,0 +1,55 @@ +define(['./voicecommands.js', './grammarprocessor.js', 'require'], function (voicecommands, grammarprocessor, require) { + + var commandgroups; + + function getCommandGroups() { + + if (commandgroups) { + return Promise.resolve(commandgroups); + } + + return new Promise(function (resolve, reject) { + + var file = "grammar"; + + require(['text!./grammar/' + file + '.json'], function (response) { + commandgroups = JSON.parse(response); + resolve(commandgroups); + }); + }); + } + /// Process the transcript described by text. + /// The text. + /// . + function processTranscript(text) { + if (text) { + var processor = grammarprocessor(commandgroups, text); + if (processor && processor.command) { + console.log("Command from Grammar Processor", processor); + return voicecommands(processor) + .then(function (result) { + console.log("Result of executed command", result); + if (result.item.actionid === 'show' && result.item.sourceid === 'group') { + return Promise.resolve({ error: "group", item: result.item, groupName: result.name }); + } else { + return Promise.resolve({ item: result.item }); + } + }, function () { + return Promise.reject({ error: "unrecognized-command", text: text }); + }); + } else { + return Promise.reject({ error: "unrecognized-command", text: text }); + } + + } else { + return Promise.reject({ error: "empty" }); + } + } + + /// An enum constant representing the window. voice input manager option. + return { + processTranscript: processTranscript, + getCommandGroups: getCommandGroups + }; + +}); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/voice/voicereceiver.js b/dashboard-ui/bower_components/emby-webcomponents/voice/voicereceiver.js new file mode 100644 index 0000000000..d25bd115fb --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/voice/voicereceiver.js @@ -0,0 +1,57 @@ +define([], function () { + var currentRecognition = null; + + + /// Starts listening for voice commands + /// . + function listenForCommand(lang) { + return new Promise(function (resolve, reject) { + cancelListener(); + + var recognition = new (window.SpeechRecognition || + window.webkitSpeechRecognition || + window.mozSpeechRecognition || + window.oSpeechRecognition || + window.msSpeechRecognition)(); + recognition.lang = lang; + + recognition.onresult = function (event) { + console.log(event); + if (event.results.length > 0) { + var resultInput = event.results[0][0].transcript || ''; + resolve(resultInput); + } + }; + + recognition.onerror = function () { + reject({ error: event.error, message: event.message }); + }; + + recognition.onnomatch = function () { + reject({ error: "no-match" }); + }; + currentRecognition = recognition; + + currentRecognition.start(); + }); + } + + + /// Cancel listener. + /// . + function cancelListener() { + + if (currentRecognition) { + currentRecognition.abort(); + currentRecognition = null; + } + + } + + /// An enum constant representing the window. voice input manager option. + return { + listenForCommand: listenForCommand, + cancel: cancelListener + }; + +}); \ No newline at end of file diff --git a/dashboard-ui/bower_components/iron-icon/.bower.json b/dashboard-ui/bower_components/iron-icon/.bower.json index f0167baf13..9784e3a3b7 100644 --- a/dashboard-ui/bower_components/iron-icon/.bower.json +++ b/dashboard-ui/bower_components/iron-icon/.bower.json @@ -32,14 +32,14 @@ "web-component-tester": "^4.0.0", "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" }, - "homepage": "https://github.com/polymerelements/iron-icon", + "homepage": "https://github.com/PolymerElements/iron-icon", "_release": "1.0.8", "_resolution": { "type": "version", "tag": "v1.0.8", "commit": "f36b38928849ef3853db727faa8c9ef104d611eb" }, - "_source": "git://github.com/polymerelements/iron-icon.git", + "_source": "git://github.com/PolymerElements/iron-icon.git", "_target": "^1.0.0", - "_originalSource": "polymerelements/iron-icon" + "_originalSource": "PolymerElements/iron-icon" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/iron-selector/.bower.json b/dashboard-ui/bower_components/iron-selector/.bower.json index 01c5a1084b..955c9dc566 100644 --- a/dashboard-ui/bower_components/iron-selector/.bower.json +++ b/dashboard-ui/bower_components/iron-selector/.bower.json @@ -36,7 +36,7 @@ "tag": "v1.5.2", "commit": "18e8e12dcd9a4560de480562f65935feed334b86" }, - "_source": "git://github.com/polymerelements/iron-selector.git", + "_source": "git://github.com/PolymerElements/iron-selector.git", "_target": "^1.0.0", - "_originalSource": "polymerelements/iron-selector" + "_originalSource": "PolymerElements/iron-selector" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/polymer/polymer.html b/dashboard-ui/bower_components/polymer/polymer.html index ff9405c9af..3e158701bb 100644 --- a/dashboard-ui/bower_components/polymer/polymer.html +++ b/dashboard-ui/bower_components/polymer/polymer.html @@ -768,7 +768,7 @@ prevent = dy > dx; prevent = dx > dy; } if (prevent) { -//ev.preventDefault(); +ev.preventDefault(); } else { Gestures.prevent('track'); } diff --git a/dashboard-ui/components/apphost.js b/dashboard-ui/components/apphost.js index 0410a4ff24..6fc05e515b 100644 --- a/dashboard-ui/components/apphost.js +++ b/dashboard-ui/components/apphost.js @@ -75,6 +75,14 @@ define(['appStorage', 'browser'], function (appStorage, browser) { return deviceName; } + function supportsVoiceInput() { + return window.SpeechRecognition || + window.webkitSpeechRecognition || + window.mozSpeechRecognition || + window.oSpeechRecognition || + window.msSpeechRecognition; + } + var appInfo; var version = window.dashboardVersion || '3.0'; @@ -96,6 +104,12 @@ define(['appStorage', 'browser'], function (appStorage, browser) { 'sharing' ]; + features.push('externallinks'); + + if (supportsVoiceInput()) { + features.push('voiceinput'); + } + return features.indexOf(command.toLowerCase()) != -1; }, appInfo: function () { diff --git a/dashboard-ui/components/tvproviders/xmltv.js b/dashboard-ui/components/tvproviders/xmltv.js index 60d3a5e196..a63f26034a 100644 --- a/dashboard-ui/components/tvproviders/xmltv.js +++ b/dashboard-ui/components/tvproviders/xmltv.js @@ -159,7 +159,7 @@ } self.submit = function () { - page.querySelector('.btnSubmitListingsContainer').click(); + page.querySelector('.btnSubmitListings').click(); }; function onSelectPathClick(e) { diff --git a/dashboard-ui/components/viewcontainer-lite.js b/dashboard-ui/components/viewcontainer-lite.js index 4cd059f0ae..252679a48c 100644 --- a/dashboard-ui/components/viewcontainer-lite.js +++ b/dashboard-ui/components/viewcontainer-lite.js @@ -50,13 +50,12 @@ define(['browser'], function (browser) { dependencies.push('legacy/dashboard'); dependencies.push('legacy/selectmenu'); dependencies.push('jqmcontrolgroup'); + dependencies.push('jqmlistview'); } if (isPluginpage || (newView.classList && newView.classList.contains('type-interior'))) { - dependencies.push('jqmlistview'); dependencies.push('scripts/notifications'); dependencies.push('dashboardcss'); - dependencies.push('emby-icons'); } return new Promise(function (resolve, reject) { diff --git a/dashboard-ui/css/librarybrowser.css b/dashboard-ui/css/librarybrowser.css index 0c97cf0589..98f46c3219 100644 --- a/dashboard-ui/css/librarybrowser.css +++ b/dashboard-ui/css/librarybrowser.css @@ -1200,7 +1200,7 @@ span.itemCommunityRating:not(:empty) + .userDataIcons { @media all and (max-width: 1200px) { .listViewUserDataButtons { - display: none; + display: none !important; } } diff --git a/dashboard-ui/css/librarymenu.css b/dashboard-ui/css/librarymenu.css index e7052af336..74a2430c2b 100644 --- a/dashboard-ui/css/librarymenu.css +++ b/dashboard-ui/css/librarymenu.css @@ -135,25 +135,11 @@ .libraryViewNav { overflow: hidden; - position: fixed; - right: 0; - left: 0; - top: 50px; z-index: 999; text-align: center; text-transform: uppercase; white-space: nowrap; padding: 0 0 0; - box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),1px 5px 1px rgba(0,0,0,.12); -} - - .libraryViewNav.bottom { - top: auto !important; - bottom: 0; - } - - -.libraryViewNav { display: flex; display: block; text-align: center; @@ -161,32 +147,45 @@ align-items: center; } - .libraryViewNav .pageTabButton { - background: transparent; - border: 0 !important; - cursor: pointer; - outline: none !important; - width: auto; - font-family: inherit; - font-size: inherit; - color: #aaa !important; - display: inline-block; - vertical-align: middle; - flex-shrink: 0; - margin: 0; - padding: 1.2em .9em; - transition: none !important; - position: relative; - text-transform: uppercase; - font-weight: bold !important; - height: auto; - min-width: initial; - line-height: initial; - border-radius: 0 !important; - overflow: hidden; - } +.ui-body-b .libraryViewNav { + box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),1px 5px 1px rgba(0,0,0,.12); + position: fixed; + right: 0; + left: 0; + top: 50px; +} - /*.libraryViewNav .pageTabButton:hover { +.libraryViewNav.bottom { + top: auto !important; + bottom: 0; +} + +.pageTabButton { + background: transparent; + border: 0 !important; + cursor: pointer; + outline: none !important; + width: auto; + font-family: inherit; + font-size: inherit; + color: #aaa !important; + display: inline-block; + vertical-align: middle; + flex-shrink: 0; + margin: 0; + padding: 1.2em .9em; + transition: none !important; + position: relative; + text-transform: uppercase; + font-weight: bold !important; + height: auto; + min-width: initial; + line-height: initial; + border-radius: 0 !important; + overflow: hidden; +} + + /*.libraryViewNav .pageTabButton:hover { background-color: transparent; } @@ -194,13 +193,13 @@ background-color: rgba(100,100,100, 0.20); }*/ - .libraryViewNav .pageTabButton:focus { - font-weight: bold !important; - } + .pageTabButton:focus { + font-weight: bold !important; + } - .libraryViewNav .pageTabButton.is-active { - color: #52B54B !important; - } + .pageTabButton.is-active { + color: #52B54B !important; + } .pageTabButtonSelectionBar { position: absolute; @@ -218,7 +217,7 @@ background: #52B54B; } -.viewMenuBar, .libraryViewNav { +.viewMenuBar, .ui-body-b .libraryViewNav { background-color: #2b2b2b; color: #fff; } @@ -252,63 +251,15 @@ width: 100%; } - .viewMenuBarTabs paper-tabs { - background: none; - box-shadow: none; - } - - .viewMenuBarTabs .paperTabLink { - align-items: center; - justify-content: center; - display: flex; - } - - - .viewMenuBarTabs #tabsContent { - display: block !important; - width: 100%; - } - - .viewMenuBarTabs #tabsContainer { - margin: auto; - -ms-flex: none; - -webkit-flex: none; - flex: none; - flex-shrink: 0; - flex-grow: 1; - touch-action: auto !important; - } - - .viewMenuBarTabs paper-tabs { - overflow: visible !important; - } - .viewMenuBarTabs .paperTabLink { padding-left: 1.5em; padding-right: 1.5em; } -.viewMenuBar paper-icon-button.paper-tabs { - display: none !important; -} - .viewMenuBar.semiTransparent { background-color: rgba(15, 15, 15, .3); } -.paperLibraryViewNav { - background-color: transparent !important; -} - -.libraryViewNav iron-icon { - display: none; -} - -.libraryViewNav::-webkit-scrollbar { - height: 0 !important; - display: none; -} - .viewMenuLink { text-decoration: none; color: #eee !important; @@ -469,13 +420,9 @@ body:not(.dashboardDocument) .headerAppsButton { padding-left: 272px; } - .mainDrawerPanel .viewMenuBarTabs paper-tab { - width: auto !important; - } - - .mainDrawerPanel .viewMenuBarTabs .tab-content { - display: block !important; - } + .viewMenuBarTabs .libraryViewNav { + text-align: left !important; + } .dashboardDocument .mainDrawer { z-index: 998 !important; diff --git a/dashboard-ui/css/site.css b/dashboard-ui/css/site.css index 311442bf64..673f2b5eec 100644 --- a/dashboard-ui/css/site.css +++ b/dashboard-ui/css/site.css @@ -226,16 +226,11 @@ div[data-role='page'] { transform: translateY(-100%); } -.libraryViewNav:not(.paperLibraryViewNav).headroom--unpinned:not(.headroomDisabled) { +.libraryViewNav.headroom--unpinned:not(.headroomDisabled) { -webkit-transform: translateY(-210%); transform: translateY(-210%); } -.paperLibraryViewNav.headroom--unpinned:not(.headroomDisabled) { - -webkit-transform: translateY(-240%); - transform: translateY(-240%); -} - .checkboxContainer { white-space: nowrap; } diff --git a/dashboard-ui/device.html b/dashboard-ui/device.html index ab2367e3ab..953f831c82 100644 --- a/dashboard-ui/device.html +++ b/dashboard-ui/device.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/devices/ios/ios.css b/dashboard-ui/devices/ios/ios.css index 733b87cb74..74d5bfffa6 100644 --- a/dashboard-ui/devices/ios/ios.css +++ b/dashboard-ui/devices/ios/ios.css @@ -40,7 +40,7 @@ body:not(.dashboardDocument) .mainDrawerButton { height: 50px; } -.viewMenuBar, .libraryViewNav, paper-tabs { +.viewMenuBar, .libraryViewNav { background-color: #000; } diff --git a/dashboard-ui/devicesupload.html b/dashboard-ui/devicesupload.html index 19c7912d78..8827d4a55f 100644 --- a/dashboard-ui/devicesupload.html +++ b/dashboard-ui/devicesupload.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/dlnaprofile.html b/dashboard-ui/dlnaprofile.html index 171290af13..0353733da8 100644 --- a/dashboard-ui/dlnaprofile.html +++ b/dashboard-ui/dlnaprofile.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/dlnasettings.html b/dashboard-ui/dlnasettings.html index 0f83e85b92..c40e6e89ed 100644 --- a/dashboard-ui/dlnasettings.html +++ b/dashboard-ui/dlnasettings.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/encodingsettings.html b/dashboard-ui/encodingsettings.html index 7baa62f5ae..dc64beaee4 100644 --- a/dashboard-ui/encodingsettings.html +++ b/dashboard-ui/encodingsettings.html @@ -9,7 +9,7 @@
${LabelHardwareAccelerationTypeHelp}
diff --git a/dashboard-ui/livetvseriestimer.html b/dashboard-ui/livetvseriestimer.html index 7b84f943b2..77d3671803 100644 --- a/dashboard-ui/livetvseriestimer.html +++ b/dashboard-ui/livetvseriestimer.html @@ -1,4 +1,4 @@ -
+
@@ -42,9 +42,8 @@ ${OptionRecordOnAllChannels}

-
-

${HeaderAdvanced}

-
+
+

diff --git a/dashboard-ui/livetvsettings.html b/dashboard-ui/livetvsettings.html index 0000d56db7..f0043a98c9 100644 --- a/dashboard-ui/livetvsettings.html +++ b/dashboard-ui/livetvsettings.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/metadata.html b/dashboard-ui/metadata.html index 53d3a1a72a..8c5a7dab8d 100644 --- a/dashboard-ui/metadata.html +++ b/dashboard-ui/metadata.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/metadataimages.html b/dashboard-ui/metadataimages.html index b66b13ac08..0c7e1387be 100644 --- a/dashboard-ui/metadataimages.html +++ b/dashboard-ui/metadataimages.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/metadatanfo.html b/dashboard-ui/metadatanfo.html index 466d7d350e..9543e577b7 100644 --- a/dashboard-ui/metadatanfo.html +++ b/dashboard-ui/metadatanfo.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/metadatasubtitles.html b/dashboard-ui/metadatasubtitles.html index d7abe7419f..1f58f7a0bb 100644 --- a/dashboard-ui/metadatasubtitles.html +++ b/dashboard-ui/metadatasubtitles.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/notificationsetting.html b/dashboard-ui/notificationsetting.html index c8ac050407..637af7ccd4 100644 --- a/dashboard-ui/notificationsetting.html +++ b/dashboard-ui/notificationsetting.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/playbackconfiguration.html b/dashboard-ui/playbackconfiguration.html index fdf94ff898..129c8ff9c6 100644 --- a/dashboard-ui/playbackconfiguration.html +++ b/dashboard-ui/playbackconfiguration.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/scheduledtask.html b/dashboard-ui/scheduledtask.html index d742edad5b..ee45541463 100644 --- a/dashboard-ui/scheduledtask.html +++ b/dashboard-ui/scheduledtask.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/scripts/episodes.js b/dashboard-ui/scripts/episodes.js index 2239c885b3..93dda46e57 100644 --- a/dashboard-ui/scripts/episodes.js +++ b/dashboard-ui/scripts/episodes.js @@ -22,7 +22,7 @@ IsMissing: false, IsVirtualUnaired: false, ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb", + EnableImageTypes: "Primary,Backdrop,Thumb", StartIndex: 0, Limit: pageSize }, diff --git a/dashboard-ui/scripts/homenextup.js b/dashboard-ui/scripts/homenextup.js index a14cc7d14c..8f0ce8fbed 100644 --- a/dashboard-ui/scripts/homenextup.js +++ b/dashboard-ui/scripts/homenextup.js @@ -8,7 +8,7 @@ Fields: "PrimaryImageAspectRatio,SeriesInfo,DateCreated,SyncInfo", UserId: Dashboard.getCurrentUserId(), ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb" + EnableImageTypes: "Primary,Backdrop,Thumb" }; return ApiClient.getNextUpEpisodes(query); diff --git a/dashboard-ui/scripts/homeupcoming.js b/dashboard-ui/scripts/homeupcoming.js index 54be1863a2..2dc1873191 100644 --- a/dashboard-ui/scripts/homeupcoming.js +++ b/dashboard-ui/scripts/homeupcoming.js @@ -7,7 +7,7 @@ var query = { Limit: 40, - Fields: "AirTime,UserData,SeriesStudio,SyncInfo", + Fields: "AirTime,UserData,SyncInfo", UserId: Dashboard.getCurrentUserId(), ImageTypeLimit: 1, EnableImageTypes: "Primary,Backdrop,Banner,Thumb", @@ -110,7 +110,6 @@ showLocationTypeIndicator: false, shape: getThumbShape(), showTitle: true, - showPremiereDate: true, preferThumb: true, lazy: true, showDetailsMenu: true, diff --git a/dashboard-ui/scripts/itemdetailpage.js b/dashboard-ui/scripts/itemdetailpage.js index e71de45a6b..ec0e0e687a 100644 --- a/dashboard-ui/scripts/itemdetailpage.js +++ b/dashboard-ui/scripts/itemdetailpage.js @@ -298,9 +298,7 @@ var section = page.querySelector('.nextUpSection'); - var userData = item.UserData || {}; - - if (item.Type != 'Series' || !userData.PlayedPercentage) { + if (item.Type != 'Series') { section.classList.add('hide'); return; } diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index 83f5ed1fc5..7d20237964 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -1330,7 +1330,7 @@ }); } - else if (item.AlbumId && item.SeriesPrimaryImageTag) { + else if (item.SeriesId && item.SeriesPrimaryImageTag) { imgUrl = ApiClient.getScaledImageUrl(item.SeriesId, { type: "Primary", @@ -2004,7 +2004,7 @@ } else if (options.preferThumb && imageItem.ParentThumbItemId && options.inheritThumb !== false) { - imgUrl = ApiClient.getThumbImageUrl(imageItem.ParentThumbItemId, { + imgUrl = ApiClient.getScaledImageUrl(imageItem.ParentThumbItemId, { type: "Thumb", maxWidth: thumbWidth, enableImageEnhancers: enableImageEnhancers @@ -2100,15 +2100,6 @@ enableImageEnhancers: enableImageEnhancers }); - } else if (imageItem.SeriesThumbImageTag) { - - imgUrl = ApiClient.getScaledImageUrl(imageItem.SeriesId, { - type: "Thumb", - maxWidth: thumbWidth, - tag: imageItem.SeriesThumbImageTag, - enableImageEnhancers: enableImageEnhancers - }); - } else if (imageItem.ParentThumbItemId) { imgUrl = ApiClient.getThumbImageUrl(imageItem, { @@ -2539,6 +2530,8 @@ getPremiereDateText: function (item, date) { + var studio = (item.Studios || [])[0]; + if (!date) { var text = ''; @@ -2547,12 +2540,12 @@ text += item.AirTime; } - if (item.SeriesStudio) { + if (studio) { if (text) { - text += " on " + item.SeriesStudio; + text += " on " + studio; } else { - text += item.SeriesStudio; + text += studio; } } @@ -2565,8 +2558,8 @@ day += " at " + item.AirTime; } - if (item.SeriesStudio) { - day += " on " + item.SeriesStudio; + if (studio) { + day += " on " + studio; } return day; diff --git a/dashboard-ui/scripts/librarymenu.js b/dashboard-ui/scripts/librarymenu.js index 61ec99cc35..5eb2cfc4d0 100644 --- a/dashboard-ui/scripts/librarymenu.js +++ b/dashboard-ui/scripts/librarymenu.js @@ -40,7 +40,7 @@ html += '
'; html += '
'; - html += '
'; + html += '
'; html += '
'; var viewMenuBar = document.createElement('div'); @@ -140,9 +140,9 @@ } } - require(['voice/voice'], function (voice) { + require(['apphost'], function (apphost) { - if (voice.isSupported()) { + if (apphost.supports('voiceinput')) { header.querySelector('.headerVoiceButton').classList.remove('hide'); } else { header.querySelector('.headerVoiceButton').classList.add('hide'); @@ -164,8 +164,8 @@ } function showVoice() { - require(['voice/voice'], function (voice) { - voice.startListening(); + require(['voiceDialog'], function (voiceDialog) { + voiceDialog.showDialog(); }); } @@ -710,22 +710,29 @@ if (LibraryMenu.tabType != type) { - require(['paper-tabs'], function () { + var index = 0; - var noInk = browserInfo.animate ? '' : ' noink'; + viewMenuBarTabs.innerHTML = '
' + builder().map(function (t) { - viewMenuBarTabs.innerHTML = '' + builder().map(function (t) { + var tabClass = selectedIndex == index ? 'pageTabButton is-active' : 'pageTabButton'; - return '
' + t.name + '
'; + var tabHtml = '' + t.name + '
'; + index++; + return tabHtml; - }).join('') + '
'; - document.body.classList.add('withTallToolbar'); - LibraryMenu.tabType = type; - }); + }).join('') + '
'; + + document.body.classList.add('withTallToolbar'); + LibraryMenu.tabType = type; return; } - viewMenuBarTabs.querySelector('paper-tabs').selected = selectedIndex; + var activeTab = viewMenuBarTabs.querySelector('.is-active'); + var newTab = viewMenuBarTabs.querySelector('.pageTabButton[data-index="' + selectedIndex + '"]'); + newTab.classList.add('is-active'); + if (newTab != activeTab && activeTab) { + activeTab.classList.remove('is-active'); + } LibraryMenu.tabType = type; }, diff --git a/dashboard-ui/scripts/moviecollections.js b/dashboard-ui/scripts/moviecollections.js index 0fd9189f53..96c6f1b80f 100644 --- a/dashboard-ui/scripts/moviecollections.js +++ b/dashboard-ui/scripts/moviecollections.js @@ -166,7 +166,7 @@ elems[i].addEventListener('click', onPreviousPageClick); } - if (!items.length) { + if (!result.Items.length) { html = '

' + Globalize.translate('MessageNoCollectionsAvailable') + '

'; } diff --git a/dashboard-ui/scripts/movietrailers.js b/dashboard-ui/scripts/movietrailers.js index dae762315b..677157d035 100644 --- a/dashboard-ui/scripts/movietrailers.js +++ b/dashboard-ui/scripts/movietrailers.js @@ -45,18 +45,18 @@ return context.savedQueryKey; } - function reloadItems(page) { + function reloadItems() { Dashboard.showLoadingMsg(); - var query = getQuery(page); + var query = getQuery(tabContent); ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) { // Scroll back up so they can see the results from the beginning window.scrollTo(0, 0); - updateFilterControls(page); + updateFilterControls(tabContent); var pagingHtml = LibraryBrowser.getQueryPagingHtml({ startIndex: query.StartIndex, @@ -147,12 +147,12 @@ function onNextPageClick() { query.StartIndex += query.Limit; - reloadItems(tabContent); + reloadItems(); } function onPreviousPageClick() { query.StartIndex -= query.Limit; - reloadItems(tabContent); + reloadItems(); } elems = tabContent.querySelectorAll('.btnNextPage'); @@ -165,7 +165,7 @@ elems[i].addEventListener('click', onPreviousPageClick); } - if (!items.length) { + if (!result.Items.length) { html = '

' + Globalize.translate('MessageNoTrailersFound') + '

'; } @@ -173,7 +173,7 @@ itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); - libraryBrowser.saveQueryValues(getSavedQueryKey(page), query); + libraryBrowser.saveQueryValues(getSavedQueryKey(tabContent), query); Dashboard.hideLoadingMsg(); }); @@ -190,7 +190,7 @@ Events.on(filterDialog, 'filterchange', function () { getQuery(tabContent).StartIndex = 0; - reloadItems(tabContent); + reloadItems(); }); filterDialog.show(); @@ -211,7 +211,7 @@ var query = getQuery(tabContent); query.NameStartsWithOrGreater = newValue; query.StartIndex = 0; - reloadItems(tabContent); + reloadItems(); }); self.alphaPicker = new alphaPicker({ @@ -255,7 +255,7 @@ }], callback: function () { getQuery(tabContent).StartIndex = 0; - reloadItems(tabContent); + reloadItems(); }, query: getQuery(tabContent), button: e.target @@ -271,7 +271,7 @@ self.renderTab = function () { - reloadItems(tabContent); + reloadItems(); updateFilterControls(tabContent); }; diff --git a/dashboard-ui/scripts/searchpage.js b/dashboard-ui/scripts/searchpage.js index c15feae70a..6df9d0b40d 100644 --- a/dashboard-ui/scripts/searchpage.js +++ b/dashboard-ui/scripts/searchpage.js @@ -187,10 +187,15 @@ }); view.addEventListener('viewbeforeshow', function (e) { + document.body.classList.add('hiddenViewMenuBar'); + document.body.classList.add('hiddenNowPlayingBar'); LibraryMenu.setMenuButtonVisible(false); }); view.addEventListener('viewbeforehide', function (e) { + + document.body.classList.remove('hiddenViewMenuBar'); + document.body.classList.remove('hiddenNowPlayingBar'); LibraryMenu.setMenuButtonVisible(true); }); diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 50462731cf..cd5d0a5a70 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -1752,6 +1752,7 @@ var AppInfo = {}; visibleinviewport: embyWebComponentsBowerPath + "/visibleinviewport", browserdeviceprofile: embyWebComponentsBowerPath + "/browserdeviceprofile", browser: embyWebComponentsBowerPath + "/browser", + inputManager: embyWebComponentsBowerPath + "/inputmanager", qualityoptions: embyWebComponentsBowerPath + "/qualityoptions", connectservice: apiClientBowerPath + '/connectservice', hammer: bowerPath + "/hammerjs/hammer.min", @@ -1814,6 +1815,7 @@ var AppInfo = {}; define("fetchHelper", [embyWebComponentsBowerPath + "/fetchhelper"], returnFirstDependency); define("tvguide", [embyWebComponentsBowerPath + "/guide/guide", 'embyRouter'], returnFirstDependency); + define("voiceDialog", [embyWebComponentsBowerPath + "/voice/voicedialog"], returnFirstDependency); define("viewManager", [embyWebComponentsBowerPath + "/viewmanager/viewmanager"], function (viewManager) { window.ViewManager = viewManager; @@ -1879,7 +1881,6 @@ var AppInfo = {}; define("emby-icons", ['webcomponentsjs', "html!" + bowerPath + "/emby-icons/emby-icons.html"]); define("paper-spinner", ['webcomponentsjs', "html!" + bowerPath + "/paper-spinner/paper-spinner.html"]); - define("paper-tabs", ['webcomponentsjs', "html!" + bowerPath + "/paper-tabs/paper-tabs.html"]); define("paper-button", ["html!" + bowerPath + "/paper-button/paper-button.html"]); define("paper-icon-button", ["html!" + bowerPath + "/paper-icon-button/paper-icon-button.html"]); define("paper-radio-group", ["html!" + bowerPath + "/paper-radio-group/paper-radio-group.html"]); @@ -1922,7 +1923,6 @@ var AppInfo = {}; define("jqmpanel", ['jqmbase', "thirdparty/jquerymobile-1.4.5/jqm.panel", 'css!thirdparty/jquerymobile-1.4.5/jqm.panel.css']); - define("iron-icon-set", ["html!" + bowerPath + "/iron-icon/iron-icon.html", "html!" + bowerPath + "/iron-iconset-svg/iron-iconset-svg.html"]); define("slideshow", [embyWebComponentsBowerPath + "/slideshow/slideshow"], returnFirstDependency); define('fetch', [bowerPath + '/fetch/fetch']); @@ -2008,16 +2008,6 @@ var AppInfo = {}; return Emby.Page; }); - // mock this for now. not used in this app - define("inputManager", [], function () { - return { - on: function () { - }, - off: function () { - } - }; - }); - // mock this for now. not used in this app define("playbackManager", [], function () { return { @@ -2083,6 +2073,22 @@ var AppInfo = {}; Dashboard.navigate('mypreferencesmenu.html?userId=' + ApiClient.getCurrentUserId()); }; + embyRouter.showGuide = function () { + Dashboard.navigate('livetv.html?tab=1'); + }; + + embyRouter.showLiveTV = function () { + Dashboard.navigate('livetv.html'); + }; + + embyRouter.showRecordedTV = function () { + Dashboard.navigate('livetv.html?tab=3'); + }; + + embyRouter.showFavorites = function () { + Dashboard.navigate('home.html?tab=3'); + }; + function showItem(item) { if (typeof (item) === 'string') { require(['connectionManager'], function (connectionManager) { @@ -2406,7 +2412,7 @@ var AppInfo = {}; defineRoute({ path: '/dashboardgeneral.html', - dependencies: ['emby-collapsible', 'paper-textarea', 'paper-input', 'paper-checkbox'], + dependencies: ['emby-collapsible', 'paper-textarea', 'paper-input', 'paper-checkbox', 'jqmlistview'], controller: 'scripts/dashboardgeneral', autoFocus: false, roles: 'admin' @@ -2595,7 +2601,7 @@ var AppInfo = {}; defineRoute({ path: '/librarysettings.html', - dependencies: ['emby-collapsible', 'paper-input', 'paper-checkbox', 'emby-button'], + dependencies: ['emby-collapsible', 'paper-input', 'paper-checkbox', 'emby-button', 'jqmlistview'], autoFocus: false, roles: 'admin', controller: 'scripts/librarysettings' diff --git a/dashboard-ui/scripts/songs.js b/dashboard-ui/scripts/songs.js index 4e42d0d1e4..9915361d8e 100644 --- a/dashboard-ui/scripts/songs.js +++ b/dashboard-ui/scripts/songs.js @@ -21,7 +21,7 @@ Limit: 100, StartIndex: 0, ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb" + EnableImageTypes: "Primary" } }; diff --git a/dashboard-ui/scripts/supporterkeypage.js b/dashboard-ui/scripts/supporterkeypage.js index 1b093bbc48..aede79c145 100644 --- a/dashboard-ui/scripts/supporterkeypage.js +++ b/dashboard-ui/scripts/supporterkeypage.js @@ -1,4 +1,4 @@ -define(['fetchHelper', 'jQuery'], function (fetchHelper, $) { +define(['fetchHelper', 'jQuery', 'registrationservices'], function (fetchHelper, $, registrationServices) { function load(page) { Dashboard.showLoadingMsg(); @@ -158,6 +158,13 @@ }]; } + function onSupporterLinkClick(e) { + + registrationServices.showPremiereInfo(); + e.preventDefault(); + e.stopPropagation(); + } + $(document).on('pageinit', "#supporterKeyPage", function () { var page = this; @@ -165,7 +172,9 @@ $('#lostKeyForm', this).on('submit', retrieveSupporterKey); $('#linkKeysForm', this).on('submit', SupporterKeyPage.linkSupporterKeys); - $('.benefits', page).html(Globalize.translate('HeaderSupporterBenefit', '', '')); + page.querySelector('.benefits').innerHTML = Globalize.translate('HeaderSupporterBenefit', '', ''); + + page.querySelector('.lnkPremiere').addEventListener('click', onSupporterLinkClick); }).on('pageshow', "#supporterKeyPage", function () { diff --git a/dashboard-ui/scripts/tvlatest.js b/dashboard-ui/scripts/tvlatest.js index 36b0d86091..dac577b3eb 100644 --- a/dashboard-ui/scripts/tvlatest.js +++ b/dashboard-ui/scripts/tvlatest.js @@ -20,7 +20,7 @@ Fields: "PrimaryImageAspectRatio,SyncInfo", ParentId: parentId, ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb" + EnableImageTypes: "Primary,Backdrop,Thumb" }; return ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)); diff --git a/dashboard-ui/scripts/tvrecommended.js b/dashboard-ui/scripts/tvrecommended.js index 1aa465677b..fa2f231323 100644 --- a/dashboard-ui/scripts/tvrecommended.js +++ b/dashboard-ui/scripts/tvrecommended.js @@ -30,7 +30,7 @@ Fields: "PrimaryImageAspectRatio,SeriesInfo,DateCreated,SyncInfo", UserId: Dashboard.getCurrentUserId(), ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb" + EnableImageTypes: "Primary,Backdrop,Thumb" }; query.ParentId = LibraryMenu.getTopParentId(); @@ -108,7 +108,7 @@ ExcludeLocationTypes: "Virtual", ParentId: parentId, ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb", + EnableImageTypes: "Primary,Backdrop,Thumb", EnableTotalRecordCount: false }; diff --git a/dashboard-ui/scripts/tvupcoming.js b/dashboard-ui/scripts/tvupcoming.js index 0110b7759a..6d6d79df2e 100644 --- a/dashboard-ui/scripts/tvupcoming.js +++ b/dashboard-ui/scripts/tvupcoming.js @@ -7,7 +7,7 @@ var query = { Limit: 40, - Fields: "AirTime,UserData,SeriesStudio,SyncInfo", + Fields: "AirTime,UserData,SyncInfo", UserId: Dashboard.getCurrentUserId(), ImageTypeLimit: 1, EnableImageTypes: "Primary,Backdrop,Banner,Thumb", @@ -112,7 +112,6 @@ showLocationTypeIndicator: false, shape: getThumbShape(), showTitle: true, - showPremiereDate: true, preferThumb: true, lazy: true, showDetailsMenu: true, diff --git a/dashboard-ui/scripts/wizardcomponents.js b/dashboard-ui/scripts/wizardcomponents.js index 875e92bc1c..2943a28dfa 100644 --- a/dashboard-ui/scripts/wizardcomponents.js +++ b/dashboard-ui/scripts/wizardcomponents.js @@ -18,7 +18,7 @@ view.querySelector('.fldSelectEncoderPathType').classList.remove('hide'); } - if (systemInfo.OperatingSystem == 'Windows' && systemInfo.SystemArchitecture != 'Arm') { + /*if (systemInfo.OperatingSystem == 'Windows' && systemInfo.SystemArchitecture != 'Arm') { view.querySelector('.suggestedLocation').innerHTML = Globalize.translate('FFmpegSuggestedDownload', 'https://ffmpeg.zeranoe.com'); @@ -29,7 +29,7 @@ instructions = 'Download FFmpeg 64-Bit Static'; } - } else if (systemInfo.OperatingSystem == 'Linux' && systemInfo.SystemArchitecture != 'Arm') { + } else*/ if (systemInfo.OperatingSystem == 'Linux' && systemInfo.SystemArchitecture != 'Arm') { view.querySelector('.suggestedLocation').innerHTML = Globalize.translate('FFmpegSuggestedDownload', 'http://johnvansickle.com/ffmpeg'); diff --git a/dashboard-ui/scripts/wizardlivetvguide.js b/dashboard-ui/scripts/wizardlivetvguide.js index bd0a4e435d..11b0749dcc 100644 --- a/dashboard-ui/scripts/wizardlivetvguide.js +++ b/dashboard-ui/scripts/wizardlivetvguide.js @@ -32,7 +32,7 @@ instance.init(); guideController = instance; - $(guideController).on('submitted', skip); + Events.on(guideController, 'submitted', skip); }); }); } diff --git a/dashboard-ui/search.html b/dashboard-ui/search.html index 9f53a05e08..b09a28c389 100644 --- a/dashboard-ui/search.html +++ b/dashboard-ui/search.html @@ -1,19 +1,38 @@ -
+
- -
+
-
-
- search -
- -
-
+
+
diff --git a/dashboard-ui/supporterkey.html b/dashboard-ui/supporterkey.html index ed7f348623..735d1a2e4f 100644 --- a/dashboard-ui/supporterkey.html +++ b/dashboard-ui/supporterkey.html @@ -1,4 +1,4 @@ -
+
@@ -48,9 +48,8 @@


-
-

${HeaderForgotKey}

-
+
+
@@ -63,10 +62,8 @@
-
-

${HeaderMultipleKeyLinking}

-
- +
+

${MultipleKeyLinkingHelp} diff --git a/dashboard-ui/themes/holiday/style.css b/dashboard-ui/themes/holiday/style.css index 0a3033ac7f..b18b3ad442 100644 --- a/dashboard-ui/themes/holiday/style.css +++ b/dashboard-ui/themes/holiday/style.css @@ -23,7 +23,7 @@ paper-button[raised].more { border-right-color: #cc3333 !important; } -paper-tabs #selectionBar, .playedIndicator { +.playedIndicator { background-color: #cc3333 !important; } diff --git a/dashboard-ui/thirdparty/paper-button-style.css b/dashboard-ui/thirdparty/paper-button-style.css index 7e19daa4cd..a9976fb723 100644 --- a/dashboard-ui/thirdparty/paper-button-style.css +++ b/dashboard-ui/thirdparty/paper-button-style.css @@ -157,25 +157,6 @@ paper-icon-button paper-ripple { color: #444 !important; } -paper-tabs { - background-color: #020202; - color: #fff; - box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.2); -} - -paper-tab { - text-transform: uppercase; - font-weight: 400; -} - -paper-tabs #selectionBar { - background-color: #52B54B !important; -} - -paper-tabs paper-ripple { - color: #52B54B !important; -} - paper-fab { vertical-align: middle; display: inline-flex !important; diff --git a/dashboard-ui/useredit.html b/dashboard-ui/useredit.html index 4cf8c177e9..0721dd7973 100644 --- a/dashboard-ui/useredit.html +++ b/dashboard-ui/useredit.html @@ -1,4 +1,4 @@ -

+
diff --git a/dashboard-ui/userlibraryaccess.html b/dashboard-ui/userlibraryaccess.html index beca75d201..f6721f4f59 100644 --- a/dashboard-ui/userlibraryaccess.html +++ b/dashboard-ui/userlibraryaccess.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/usernew.html b/dashboard-ui/usernew.html index faaec13cb0..4c9fa8c8a0 100644 --- a/dashboard-ui/usernew.html +++ b/dashboard-ui/usernew.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/userparentalcontrol.html b/dashboard-ui/userparentalcontrol.html index 4b28d65ded..889d984d22 100644 --- a/dashboard-ui/userparentalcontrol.html +++ b/dashboard-ui/userparentalcontrol.html @@ -1,4 +1,4 @@ -
+
diff --git a/dashboard-ui/voice/commands/controlcommands.js b/dashboard-ui/voice/commands/controlcommands.js deleted file mode 100644 index 46d27418f0..0000000000 --- a/dashboard-ui/voice/commands/controlcommands.js +++ /dev/null @@ -1,11 +0,0 @@ - -define([], function () { - - return function (result) { - result.success = true; - if (result.properties.devicename) - MediaController.trySetActiveDeviceName(result.properties.devicename); - - return; - } -}); \ No newline at end of file diff --git a/dashboard-ui/voice/commands/searchcommands.js b/dashboard-ui/voice/commands/searchcommands.js deleted file mode 100644 index 6338fecd5f..0000000000 --- a/dashboard-ui/voice/commands/searchcommands.js +++ /dev/null @@ -1,16 +0,0 @@ - -define([], function () { - - return function (result) { - result.success = true; - switch (result.item.deviceid) { - case 'displaymirroring': - MediaController.enableDisplayMirroring(false); - break; - default: - result.success = false; - return; - } - } - -}); \ No newline at end of file diff --git a/dashboard-ui/voice/commands/showcommands.js b/dashboard-ui/voice/commands/showcommands.js deleted file mode 100644 index 81850a657d..0000000000 --- a/dashboard-ui/voice/commands/showcommands.js +++ /dev/null @@ -1,93 +0,0 @@ - -define([], function () { - - return function (result) { - result.success = true; - switch (result.item.sourceid) { - case 'music': - Dashboard.navigate('music.html'); - break; - case 'movies': - if (result.properties.movieName) { - //TODO: Find a way to display movie - var query = { - - Limit: 1, - UserId: result.userId, - ExcludeLocationTypes: "Virtual" - }; - - - if (result.item.itemType) { - query.IncludeItemTypes = result.item.itemType; - } - - query.SearchTerm = result.properties.movieName; - - ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (queryResult) { - - var s = queryResult[0]; - - }); - - } - else - Dashboard.navigate('movies.html'); - - break; - case 'tvseries': - Dashboard.navigate('tv.html'); - break; - case 'livetv': - var act = result.item.menuid; - if (act) { - if (act.indexOf('livetv') != -1) - Dashboard.navigate('livetv.html?tab=0'); - else if (act.indexOf('guide') != -1) - Dashboard.navigate('livetv.html?tab=1'); - else if (act.indexOf('channels') != -1) - Dashboard.navigate('livetv.html?tab=2'); - else if (act.indexOf('recordings') != -1) - Dashboard.navigate('livetv.html?tab=3'); - else if (act.indexOf('scheduled') != -1) - Dashboard.navigate('livetv.html?tab=4'); - else if (act.indexOf('series') != -1) - Dashboard.navigate('livetv.html?tab=5'); - else - Dashboard.navigate('livetv.html?tab=0'); - } - else - Dashboard.navigate('livetv.html?tab=0'); - break; - case 'recordings': - Dashboard.navigate('livetv.html?tab=3'); - break; - case 'latestepisodes': - Dashboard.navigate('tv.html?tab=1'); - case 'home': - var act = result.item.menuid; - if (act) { - if (act.indexOf('home') != -1) - Dashboard.navigate('index.html'); - else if (act.indexOf('nextup') != -1) - Dashboard.navigate('index.html?tab=2'); - else if (act.indexOf('favorites') != -1) - Dashboard.navigate('index.html?tab=2'); - else if (act.indexOf('upcoming') != -1) - Dashboard.navigate('index.html?tab=3'); - else if (act.indexOf('nowplaying') != -1) - Dashboard.navigate('nowplaying.html'); - else - Dashboard.navigate('index.html'); - } - else - Dashboard.navigate('index.html'); - case 'group': - break; - default: - result.success = false; - return; - } - - } -}); \ No newline at end of file diff --git a/dashboard-ui/voice/voice.js b/dashboard-ui/voice/voice.js deleted file mode 100644 index b48664f3c1..0000000000 --- a/dashboard-ui/voice/voice.js +++ /dev/null @@ -1,28 +0,0 @@ -define([], function () { - - return { - - isSupported: function () { - - if (AppInfo.isNativeApp) { - // Crashes on some amazon devices - if (window.device && (device.platform || '').toLowerCase().indexOf('amazon') != -1) { - return false; - } - } - - return window.SpeechRecognition || - window.webkitSpeechRecognition || - window.mozSpeechRecognition || - window.oSpeechRecognition || - window.msSpeechRecognition; - }, - - startListening: function () { - require(['voice/voicedialog'], function (voicedialog) { - voicedialog.startListening(); - }); - } - }; - -}); \ No newline at end of file diff --git a/dashboard-ui/voice/voicedialog.js b/dashboard-ui/voice/voicedialog.js deleted file mode 100644 index 64445c2a35..0000000000 --- a/dashboard-ui/voice/voicedialog.js +++ /dev/null @@ -1,332 +0,0 @@ -define(['dialogHelper', 'jQuery', 'emby-button'], function (dialogHelper, $) { - - var currentRecognition; - var lang = 'en-US'; - - var commandgroups; - - function getCommandGroups() { - - if (commandgroups) { - return Promise.resolve(commandgroups); - } - - return new Promise(function (resolve, reject) { - - var file = "grammar"; - //if (language && language.length > 0) - // file = language; - - var xhr = new XMLHttpRequest(); - xhr.open('GET', "voice/grammar/" + file + ".json", true); - - xhr.onload = function (e) { - - commandgroups = JSON.parse(this.response); - resolve(commandgroups); - } - - xhr.onerror = reject; - - xhr.send(); - }); - } - - /// Shuffle array. - /// The array. - /// array - function shuffleArray(array) { - var currentIndex = array.length, temporaryValue, randomIndex; - - // While there remain elements to shuffle... - while (0 !== currentIndex) { - - // Pick a remaining element... - randomIndex = Math.floor(Math.random() * currentIndex); - currentIndex -= 1; - - // And swap it with the current element. - temporaryValue = array[currentIndex]; - array[currentIndex] = array[randomIndex]; - array[randomIndex] = temporaryValue; - } - - return array; - } - - /// Gets sample commands. - /// The sample commands. - function getSampleCommands(groupid) { - - return getCommandGroups().then(function (commandGroups) { - groupid = typeof (groupid) !== 'undefined' ? groupid : ''; - - var commands = []; - commandGroups.map(function (group) { - if ((group.items && group.items.length > 0) && (groupid == group.groupid || groupid == '')) { - - group.items.map(function (item) { - - if (item.commandtemplates && item.commandtemplates.length > 0) { - - item.commandtemplates.map(function (templates) { - commands.push(templates); - }); - } - - }); - } - }); - - return shuffleArray(commands); - }); - } - - /// Gets command group. - /// The groupid. - /// The command group. - function getCommandGroup(groupid) { - if (commandgroups) { - var idx = -1; - idx = commandgroups.map(function (e) { return e.groupid; }).indexOf(groupid); - - if (idx > -1) - return commandgroups[idx]; - else - return null; - } - else - return null; - } - - /// Renders the sample commands. - /// The element. - /// The commands. - /// . - function renderSampleCommands(elem, commands) { - - commands.length = Math.min(commands.length, 4); - - commands = commands.map(function (c) { - - return '
"' + c + '"
'; - - }).join(''); - - $('.exampleCommands', elem).html(commands); - } - - var currentDialog; - /// Shows the voice help. - /// . - function showVoiceHelp(groupid, title) { - - var dlg = dialogHelper.createDialog({ - size: 'medium', - removeOnClose: true - }); - - dlg.classList.add('ui-body-b'); - dlg.classList.add('background-theme-b'); - - var html = ''; - html += '

'; - html += ''; - if (groupid) { - var grp = getCommandGroup(groupid); - if (grp) - html += ' ' + grp.name; - } - html += '

'; - - html += '
'; - - var getCommandsPromise = getSampleCommands(groupid); - - html += '
'; - - html += '
'; - - html += '

' + Globalize.translate('HeaderSaySomethingLike') + '

'; - - html += '
'; - html += '
'; - - // defaultVoiceHelp - html += '
'; - - html += ''; - - html += ''; - - // voiceHelpContent - html += '
'; - - html += '
'; - - dlg.innerHTML = html; - document.body.appendChild(dlg); - - dialogHelper.open(dlg); - currentDialog = dlg; - - dlg.addEventListener('close', function () { - currentDialog = null; - }); - - $('.btnCancelVoiceInput', dlg).on('click', function () { - destroyCurrentRecognition(); - dialogHelper.close(dlg); - }); - - $('.btnRetry', dlg).on('click', function () { - $('.unrecognizedCommand').hide(); - $('.defaultVoiceHelp').show(); - startListening(false); - }); - - getCommandsPromise.then(function (commands) { - renderSampleCommands(dlg.querySelector('.voiceHelpContent'), commands); - }); - } - - /// Hides the voice help. - /// . - function hideVoiceHelp() { - - $('.voiceInputHelp').remove(); - } - - /// Shows the unrecognized command help. - /// . - function showUnrecognizedCommandHelp() { - //speak("I don't understend this command"); - $('.unrecognizedCommand').show(); - $('.defaultVoiceHelp').hide(); - } - - /// Process the transcript described by text. - /// The text. - /// . - function processTranscript(text, isCancelled) { - - $('.voiceInputText').html(text); - - if (text || AppInfo.isNativeApp) { - $('.blockedMessage').hide(); - } - else { - $('.blockedMessage').show(); - } - - if (text) { - require(['voice/voicecommands.js', 'voice/grammarprocessor.js'], function (voicecommands, grammarprocessor) { - - var processor = grammarprocessor(commandgroups, text); - if (processor && processor.command) { - voicecommands(processor) - .then(function (result) { - if (result.item.actionid === 'show' && result.item.sourceid === 'group') { - var dlg = currentDialog; - if (dlg) - showCommands(false, result) - else - showCommands(true, result) - } - }) - .catch(showUnrecognizedCommandHelp); - } - else - showUnrecognizedCommandHelp(); - - var dlg = currentDialog; - if (dlg) { - dialogHelper.close(dlg); - } - }); - - } - else if (!isCancelled) { - showUnrecognizedCommandHelp(); - } - } - - /// Starts listening internal. - /// . - function startListening(createUI) { - - destroyCurrentRecognition(); - var recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.oSpeechRecognition || window.msSpeechRecognition)(); - recognition.lang = lang; - var groupid = ''; - //recognition.continuous = true; - //recognition.interimResults = true; - - recognition.onresult = function (event) { - if (event.results.length > 0) { - processTranscript(event.results[0][0].transcript || ''); - } - }; - - recognition.onerror = function () { - processTranscript('', recognition.cancelled); - }; - - recognition.onnomatch = function () { - processTranscript('', recognition.cancelled); - }; - - recognition.start(); - currentRecognition = recognition; - showCommands(createUI); - } - - /// Destroys the current recognition. - /// . - function destroyCurrentRecognition() { - - var recognition = currentRecognition; - if (recognition) { - recognition.abort(); - currentRecognition = null; - } - } - - /// Cancel listener. - /// . - function cancelListener() { - - destroyCurrentRecognition(); - hideVoiceHelp(); - } - - /// Shows the commands. - /// The create user interface. - /// . - function showCommands(createUI, result) { - if (createUI !== false) { - //speak('Hello, what can I do for you?'); - require(['paper-fab', 'css!voice/voice.css'], function () { - if (result) - showVoiceHelp(result.groupid, result.name); - else - showVoiceHelp(); - }); - } - } - - /// An enum constant representing the window. voice input manager option. - return { - startListening: startListening - }; - -}); \ No newline at end of file diff --git a/dashboard-ui/wizardlivetvguide.html b/dashboard-ui/wizardlivetvguide.html index 134dea36bd..f871dac182 100644 --- a/dashboard-ui/wizardlivetvguide.html +++ b/dashboard-ui/wizardlivetvguide.html @@ -16,6 +16,7 @@
${AdditionalLiveTvProvidersCanBeInstalledLater}