diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-button/emby-button.css b/dashboard-ui/bower_components/emby-webcomponents/emby-button/emby-button.css index 0df4212d84..38d7ad3604 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/emby-button/emby-button.css +++ b/dashboard-ui/bower_components/emby-webcomponents/emby-button/emby-button.css @@ -212,3 +212,8 @@ opacity: 0; } } + +.emby-button-foreground { + position: relative; + z-index: 1; +} diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-tabs/emby-tabs.css b/dashboard-ui/bower_components/emby-webcomponents/emby-tabs/emby-tabs.css new file mode 100644 index 0000000000..1ffd6cdf0d --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/emby-tabs/emby-tabs.css @@ -0,0 +1,94 @@ +.emby-tab-button { + 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; +} + + .emby-tab-button:focus { + font-weight: bold !important; + } + +.emby-tab-button-active { + color: #52B54B !important; +} + +.emby-tabs-slider { + position: relative; +} + +.emby-tabs-selection-bar { + position: absolute; + left: 0; + /* Need this or it will be partially covered by the drop-shadow on android */ + bottom: 1px; + height: 2px; + z-index: 1000; + background: #52B54B; + width: 0; +} + +.emby-tab-button-selection-bar { + position: absolute; + left: 0; + border: 0; + /* Need this or it will be partially covered by the drop-shadow on android */ + bottom: 1px; + height: 2px; + right: 0; + border-radius: 0; + z-index: 1000; +} + +.emby-tab-button-selection-bar-active { + background: #52B54B; +} + +.emby-tab-button-ripple-effect { + position: absolute !important; + top: 0 !important; + left: 0 !important; + right: 0 !important; + bottom: 0 !important; + width: auto !important; + height: auto !important; + background: #181818 !important; + animation: emby-tab-button-ripple-animation .8s !important; + transform-origin: center center !important; + border-radius: 0; +} + +@keyframes emby-tab-button-ripple-animation { + 0% { + transform: scale(.2, 1); + opacity: 0.5; + } + + 50% { + transform: none; + opacity: 1; + } + + 100% { + transform: none; + opacity: 0; + } +} diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-tabs/emby-tabs.js b/dashboard-ui/bower_components/emby-webcomponents/emby-tabs/emby-tabs.js new file mode 100644 index 0000000000..4df2fada52 --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/emby-tabs/emby-tabs.js @@ -0,0 +1,309 @@ +define(['dom', 'scroller', 'browser', 'registerElement', 'css!./emby-tabs', 'scrollStyles'], function (dom, scroller, browser) { + + var EmbyTabs = Object.create(HTMLDivElement.prototype); + var buttonClass = 'emby-tab-button'; + var activeButtonClass = buttonClass + '-active'; + + function getBoundingClientRect(elem) { + + // Support: BlackBerry 5, iOS 3 (original iPhone) + // If we don't have gBCR, just use 0,0 rather than error + if (elem.getBoundingClientRect) { + return elem.getBoundingClientRect(); + } else { + return { top: 0, left: 0 }; + } + } + + function getButtonSelectionBar(tabButton) { + var elem = tabButton.querySelector('.' + buttonClass + '-selection-bar'); + + if (!elem) { + elem = document.createElement('div'); + elem.classList.add(buttonClass + '-selection-bar'); + tabButton.appendChild(elem); + } + + return elem; + } + + function hideButtonSelectionBar(tabButton) { + + var elem = getButtonSelectionBar(tabButton); + + elem.classList.add('hide'); + elem.classList.remove('emby-tab-button-selection-bar-active'); + } + + function showButtonSelectionBar(tabButton) { + var elem = getButtonSelectionBar(tabButton); + + elem.classList.remove('hide'); + elem.classList.add('emby-tab-button-selection-bar-active'); + } + + function animtateSelectionBar(bar, start, pos, duration) { + + var endTransform = pos ? ('translateX(' + pos + 'px)') : 'none'; + var startTransform = start ? ('translateX(' + start + 'px)') : 'none'; + + if (!duration || !bar.animate) { + bar.style.transform = endTransform; + return; + } + + bar.style.transform = startTransform; + + var keyframes = [ + { transform: 'translateX(' + start + 'px)', offset: 0 }, + { transform: endTransform, offset: 1 }]; + + bar.animate(keyframes, { + duration: duration, + iterations: 1, + easing: 'ease-out', + fill: 'forwards' + }); + } + + function moveSelectionBar(tabs, newButton, oldButton, animate) { + + if (oldButton) { + hideButtonSelectionBar(oldButton); + } + hideButtonSelectionBar(newButton); + + var selectionBar = tabs.selectionBar; + + if (selectionBar) { + selectionBar.style.width = newButton.offsetWidth + 'px'; + selectionBar.classList.remove('hide'); + } + + var tabsOffset = getBoundingClientRect(tabs); + var startOffset = tabs.currentOffset || 0; + + if (oldButton) { + if (tabs.scroller) { + startOffset = tabs.scroller.getCenterPosition(oldButton); + } else { + startOffset = getBoundingClientRect(oldButton).left - tabsOffset.left; + } + } + + var endPosition; + if (tabs.scroller) { + endPosition = tabs.scroller.getCenterPosition(newButton); + } else { + var tabButtonOffset = getBoundingClientRect(newButton); + endPosition = tabButtonOffset.left - tabsOffset.left; + } + + var delay = animate ? 180 : 0; + if (selectionBar) { + animtateSelectionBar(selectionBar, startOffset, endPosition, delay); + } + tabs.currentOffset = endPosition; + + newButton.classList.add(activeButtonClass); + + setTimeout(function () { + + showButtonSelectionBar(newButton); + if (selectionBar) { + selectionBar.classList.add('hide'); + } + + }, delay); + } + + function onClick(e) { + + var tabs = this; + + var current = tabs.querySelector('.' + activeButtonClass); + var tabButton = dom.parentWithClass(e.target, buttonClass); + + if (tabButton && tabButton != current) { + + if (current) { + current.classList.remove(activeButtonClass); + } + + var previousIndex = current ? parseInt(current.getAttribute('data-index')) : null; + + moveSelectionBar(tabs, tabButton, current, true); + var index = parseInt(tabButton.getAttribute('data-index')); + + tabs.dispatchEvent(new CustomEvent("beforetabchange", { + detail: { + selectedTabIndex: index, + previousIndex: previousIndex + } + })); + + // If toCenter is called syncronously within the click event, it sometimes ends up canceling it + setTimeout(function () { + + tabs.selectedTabIndex = index; + + tabs.dispatchEvent(new CustomEvent("tabchange", { + detail: { + selectedTabIndex: index, + previousIndex: previousIndex + } + })); + }, 120); + + if (tabs.scroller) { + tabs.scroller.toCenter(tabButton, false); + } + + } + } + + function initScroller(tabs) { + + if (tabs.scroller) { + return; + } + + var contentScrollSlider = tabs.querySelector('.emby-tabs-slider'); + if (contentScrollSlider) { + tabs.scroller = new scroller(tabs, { + horizontal: 1, + itemNav: 0, + mouseDragging: 1, + touchDragging: 1, + slidee: contentScrollSlider, + smart: true, + releaseSwing: true, + scrollBy: 200, + speed: 120, + elasticBounds: 1, + dragHandle: 1, + dynamicHandle: 1, + clickBar: 1, + hiddenScroll: true, + + // In safari the transform is causing the headers to occasionally disappear or flicker + requireAnimation: !browser.safari + }); + tabs.scroller.init(); + } else { + tabs.classList.add('hiddenScrollX'); + } + } + + function initSelectionBar(tabs) { + + var contentScrollSlider = tabs.querySelector('.emby-tabs-slider'); + + if (!contentScrollSlider) { + return; + } + + var elem = document.createElement('div'); + elem.classList.add('emby-tabs-selection-bar'); + + contentScrollSlider.appendChild(elem); + tabs.selectionBar = elem; + } + + EmbyTabs.createdCallback = function () { + + if (this.classList.contains('emby-tabs')) { + return; + } + this.classList.add('emby-tabs'); + + dom.addEventListener(this, 'click', onClick, { + passive: true + }); + + initSelectionBar(this); + }; + + EmbyTabs.attachedCallback = function () { + + initScroller(this); + + var current = this.querySelector('.' + activeButtonClass); + var currentIndex = current ? parseInt(current.getAttribute('data-index')) : 0; + + var newTabButton = this.querySelectorAll('.' + buttonClass)[currentIndex]; + + if (newTabButton) { + moveSelectionBar(this, newTabButton, current, false); + } + }; + + EmbyTabs.detachedCallback = function () { + + if (this.scroller) { + this.scroller.destroy(); + this.scroller = null; + } + + dom.removeEventListener(this, 'click', onClick, { + passive: true + }); + this.selectionBar = null; + }; + + EmbyTabs.selectedIndex = function (selected) { + + var tabs = this; + + if (selected == null) { + + return tabs.selectedTabIndex || 0; + } + + var current = tabs.selectedIndex(); + + tabs.selectedTabIndex = selected; + + var tabButtons = tabs.querySelectorAll('.' + buttonClass); + + if (current == selected) { + + tabs.dispatchEvent(new CustomEvent("beforetabchange", { + detail: { + selectedTabIndex: selected + } + })); + tabs.dispatchEvent(new CustomEvent("tabchange", { + detail: { + selectedTabIndex: selected + } + })); + + moveSelectionBar(tabs, tabButtons[selected], tabButtons[selected], false); + } else { + tabButtons[selected].click(); + } + }; + + EmbyTabs.triggerTabChange = function (selected) { + + var tabs = this; + + tabs.dispatchEvent(new CustomEvent("beforetabchange", { + detail: { + selectedTabIndex: tabs.selectedIndex() + } + })); + + tabs.dispatchEvent(new CustomEvent("tabchange", { + detail: { + selectedTabIndex: tabs.selectedIndex() + } + })); + }; + + document.registerElement('emby-tabs', { + prototype: EmbyTabs, + extends: 'div' + }); +}); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/scroller/smoothscroller.js b/dashboard-ui/bower_components/emby-webcomponents/scroller/smoothscroller.js index 995a8e372b..6f66bbe0fc 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/scroller/smoothscroller.js +++ b/dashboard-ui/bower_components/emby-webcomponents/scroller/smoothscroller.js @@ -475,6 +475,12 @@ define(['browser', 'layoutManager', 'dom', 'scrollStyles'], function (browser, l }; }; + self.getCenterPosition = function(item) { + + var pos = self.getPos(item); + return within(pos.center, pos.start, pos.end); + }; + /** * Slide SLIDEE by amount of pixels. * diff --git a/dashboard-ui/channels.html b/dashboard-ui/channels.html index 049b89f7c2..4e442131fe 100644 --- a/dashboard-ui/channels.html +++ b/dashboard-ui/channels.html @@ -1,9 +1,16 @@ 
-
- - +
+
+ + +
+
diff --git a/dashboard-ui/css/librarymenu.css b/dashboard-ui/css/librarymenu.css index 3582212bbf..86240a33b2 100644 --- a/dashboard-ui/css/librarymenu.css +++ b/dashboard-ui/css/librarymenu.css @@ -151,63 +151,6 @@ 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; - } - - .libraryViewNav .pageTabButton:active { - background-color: rgba(100,100,100, 0.20); - }*/ - - .pageTabButton:focus { - font-weight: bold !important; - } - - .pageTabButton.is-active { - color: #52B54B !important; - } - -.pageTabButtonSelectionBar { - position: absolute; - left: 0; - border: 0; - /* Need this or it will be partially covered by the drop-shadow on android */ - bottom: 1px; - height: 2px; - right: 0; - border-radius: 0; - z-index: 1000; -} - -.pageTabButton.is-active .pageTabButtonSelectionBar { - background: #52B54B; -} - .viewMenuBar, .ui-body-b .libraryViewNav { background-color: #222326; color: #fff; diff --git a/dashboard-ui/devices/android/android.css b/dashboard-ui/devices/android/android.css index 200bf4b333..3f1643b96d 100644 --- a/dashboard-ui/devices/android/android.css +++ b/dashboard-ui/devices/android/android.css @@ -5,7 +5,7 @@ flex-grow: 1; } - .libraryViewNav .pageTabButton { + .libraryViewNav .emby-tab-button { flex-grow: 1; } } diff --git a/dashboard-ui/devices/ios/ios.css b/dashboard-ui/devices/ios/ios.css index 387e417307..d54bc64d24 100644 --- a/dashboard-ui/devices/ios/ios.css +++ b/dashboard-ui/devices/ios/ios.css @@ -41,16 +41,16 @@ body:not(.dashboardDocument) .mainDrawerButton { background-color: #000; } -.libraryViewNav .pageTabButton { +.libraryViewNav .emby-tab-button { font-weight: 400; text-transform: none; } -.pageTabButton.is-active .pageTabButtonSelectionBar { +.emby-tab-button-selection-bar { display: none !important; } -.libraryViewNav .pageTabButton.is-active { +.libraryViewNav .emby-tab-button-active { color: #52B54B !important; } diff --git a/dashboard-ui/home.html b/dashboard-ui/home.html index 8cb01e420f..3a4ba42255 100644 --- a/dashboard-ui/home.html +++ b/dashboard-ui/home.html @@ -1,10 +1,20 @@ 
-
- - - - +
+
+ + + + +
diff --git a/dashboard-ui/livetv.html b/dashboard-ui/livetv.html index 9bed4c8d3c..82bf5d23e8 100644 --- a/dashboard-ui/livetv.html +++ b/dashboard-ui/livetv.html @@ -1,14 +1,25 @@ 
-
-
- - - - - +
+
+ + + + +
+

${HeaderWhatsOnTV}

diff --git a/dashboard-ui/movies.html b/dashboard-ui/movies.html index 8f61cb21f9..37a98da913 100644 --- a/dashboard-ui/movies.html +++ b/dashboard-ui/movies.html @@ -1,13 +1,25 @@ 
-
-
- - - - - - +
+
+ + + + + +
diff --git a/dashboard-ui/music.html b/dashboard-ui/music.html index 2331ac1cb9..d372d3cf4c 100644 --- a/dashboard-ui/music.html +++ b/dashboard-ui/music.html @@ -1,16 +1,31 @@ 
-
-
- - - - - - - +
+
+ + + + + + +
+

${HeaderLatestMusic}

diff --git a/dashboard-ui/nowplaying.html b/dashboard-ui/nowplaying.html index 86b6e3d221..484a3cbc36 100644 --- a/dashboard-ui/nowplaying.html +++ b/dashboard-ui/nowplaying.html @@ -14,11 +14,20 @@
-
- - - +
+
+ + + +
+
diff --git a/dashboard-ui/scripts/channels.js b/dashboard-ui/scripts/channels.js index f01feeef28..d5e2934679 100644 --- a/dashboard-ui/scripts/channels.js +++ b/dashboard-ui/scripts/channels.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'cardBuilder', 'emby-itemscontainer'], function (libraryBrowser, cardBuilder) { +define(['libraryBrowser', 'cardBuilder', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (libraryBrowser, cardBuilder) { // The base query options var query = { diff --git a/dashboard-ui/scripts/indexpage.js b/dashboard-ui/scripts/indexpage.js index 45eb6e25f3..bd11cf8f53 100644 --- a/dashboard-ui/scripts/indexpage.js +++ b/dashboard-ui/scripts/indexpage.js @@ -1,4 +1,4 @@ -define(['libraryBrowser'], function (libraryBrowser) { +define(['libraryBrowser', 'emby-tabs', 'emby-button'], function (libraryBrowser) { var defaultFirstSection = 'smalllibrarytiles'; @@ -343,11 +343,7 @@ if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') { - mdlTabs.dispatchEvent(new CustomEvent("tabchange", { - detail: { - selectedTabIndex: libraryBrowser.selectedTab(mdlTabs) - } - })); + mdlTabs.triggerTabChange(); } } diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index fff150844f..00b4051cb3 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -1,8 +1,8 @@ -define(['viewManager', 'appSettings', 'appStorage', 'apphost', 'datetime', 'itemHelper', 'mediaInfo', 'scroller', 'indicators', 'dom', 'imageLoader', 'scrollStyles'], function (viewManager, appSettings, appStorage, appHost, datetime, itemHelper, mediaInfo, scroller, indicators, dom) { +define(['viewManager', 'appSettings', 'appStorage', 'apphost', 'datetime', 'itemHelper', 'mediaInfo', 'scroller', 'indicators', 'dom', 'browser', 'imageLoader', 'scrollStyles'], function (viewManager, appSettings, appStorage, appHost, datetime, itemHelper, mediaInfo, scroller, indicators, dom, browser) { function fadeInRight(elem) { - var pct = browserInfo.mobile ? '4%' : '0.5%'; + var pct = browser.mobile ? '4%' : '0.5%'; var keyframes = [ { opacity: '0', transform: 'translate3d(' + pct + ', 0, 0)', offset: 0 }, @@ -15,28 +15,6 @@ }); } - function animateSelectionBar(button) { - - var elem = button.querySelector('.pageTabButtonSelectionBar'); - - if (!elem) { - return; - } - - var keyframes = [ - { transform: 'translate3d(-100%, 0, 0)', offset: 0 }, - { transform: 'none', offset: 1 }]; - - if (!elem.animate) { - return; - } - elem.animate(keyframes, { - duration: 120, - iterations: 1, - easing: 'ease-out' - }); - } - var libraryBrowser = (function (window, document, screen) { var pageSizeKey = 'pagesize_v4'; @@ -135,35 +113,9 @@ return true; }, - selectedTab: function (tabs, selected) { - - if (selected == null) { - - return tabs.selectedTabIndex || 0; - } - - var current = LibraryBrowser.selectedTab(tabs); - tabs.selectedTabIndex = selected; - if (current == selected) { - tabs.dispatchEvent(new CustomEvent("beforetabchange", { - detail: { - selectedTabIndex: selected - } - })); - tabs.dispatchEvent(new CustomEvent("tabchange", { - detail: { - selectedTabIndex: selected - } - })); - } else { - var tabButtons = tabs.querySelectorAll('.pageTabButton'); - tabButtons[selected].click(); - } - }, - configureSwipeTabs: function (ownerpage, tabs) { - if (!browserInfo.touch) { + if (!browser.touch) { return; } @@ -176,18 +128,18 @@ hammertime.on('swipeleft', function (e) { if (LibraryBrowser.allowSwipe(e.target)) { - var selected = parseInt(LibraryBrowser.selectedTab(tabs) || '0'); + var selected = parseInt(tabs.selectedIndex() || '0'); if (selected < (pageCount - 1)) { - LibraryBrowser.selectedTab(tabs, selected + 1); + tabs.selectedIndex(selected + 1); } } }); hammertime.on('swiperight', function (e) { if (LibraryBrowser.allowSwipe(e.target)) { - var selected = parseInt(LibraryBrowser.selectedTab(tabs) || '0'); + var selected = parseInt(tabs.selectedIndex() || '0'); if (selected > 0) { - LibraryBrowser.selectedTab(tabs, selected - 1); + tabs.selectedIndex(selected - 1); } } }); @@ -196,150 +148,62 @@ configurePaperLibraryTabs: function (ownerpage, tabs, panels, animateTabs) { - if (!browserInfo.safari) { + if (!browser.safari) { LibraryBrowser.configureSwipeTabs(ownerpage, tabs); } - if (!browserInfo.safari || !AppInfo.isNativeApp) { - var buttons = tabs.querySelectorAll('.pageTabButton'); - for (var i = 0, length = buttons.length; i < length; i++) { - var div = document.createElement('div'); - div.classList.add('pageTabButtonSelectionBar'); - buttons[i].appendChild(div); - } - } + ownerpage.addEventListener('viewshow', LibraryBrowser.onTabbedpagebeforeshow); - tabs.addEventListener('click', function (e) { - - var current = tabs.querySelector('.is-active'); - var link = dom.parentWithClass(e.target, 'pageTabButton'); - - if (link && link != current) { - - if (current) { - current.classList.remove('is-active'); - panels[parseInt(current.getAttribute('data-index'))].classList.remove('is-active'); - } - - link.classList.add('is-active'); - animateSelectionBar(link); - var index = parseInt(link.getAttribute('data-index')); - var newPanel = panels[index]; - - tabs.dispatchEvent(new CustomEvent("beforetabchange", { - detail: { - selectedTabIndex: index - } - })); - - // If toCenter is called syncronously within the click event, it sometimes ends up canceling it - setTimeout(function () { - - if (animateTabs && animateTabs.indexOf(index) != -1 && /*browserInfo.animate &&*/ newPanel.animate) { - fadeInRight(newPanel); - } - - tabs.selectedTabIndex = index; - - tabs.dispatchEvent(new CustomEvent("tabchange", { - detail: { - selectedTabIndex: index - } - })); - - newPanel.classList.add('is-active'); - }, 120); - - if (tabs.scroller) { - tabs.scroller.toCenter(link, false); - } + tabs.addEventListener('beforetabchange', function(e) { + if (e.detail.previousIndex != null) { + panels[e.detail.previousIndex].classList.remove('is-active'); } }); - ownerpage.addEventListener('viewbeforeshow', LibraryBrowser.onTabbedpagebeforeshow); + tabs.addEventListener('beforetabchange', function (e) { - var contentScrollSlider = tabs.querySelector('.contentScrollSlider'); - if (contentScrollSlider) { - tabs.scroller = new scroller(tabs, { - horizontal: 1, - itemNav: 0, - mouseDragging: 1, - touchDragging: 1, - slidee: tabs.querySelector('.contentScrollSlider'), - smart: true, - releaseSwing: true, - scrollBy: 200, - speed: 120, - elasticBounds: 1, - dragHandle: 1, - dynamicHandle: 1, - clickBar: 1, - //centerOffset: window.innerWidth * .05, - hiddenScroll: true, + var newPanel = panels[e.detail.selectedTabIndex]; - // In safari the transform is causing the headers to occasionally disappear or flicker - requireAnimation: !browserInfo.safari - }); - tabs.scroller.init(); - } else { - tabs.classList.add('hiddenScrollX'); - } + if (e.detail.previousIndex != null && e.detail.previousIndex != e.detail.selectedTabIndex) { + if (newPanel.animate && (animateTabs || []).indexOf(e.detail.selectedTabIndex) != -1) { + fadeInRight(newPanel); + } + } + + newPanel.classList.add('is-active'); + }); }, onTabbedpagebeforeshow: function (e) { var page = e.target; var delay = 0; - var isFirstLoad = false; - if (!page.getAttribute('data-firstload')) { + var pageTabsContainer = page.querySelector('.libraryViewNav'); + if (!pageTabsContainer || !pageTabsContainer.triggerTabChange) { delay = 300; - isFirstLoad = true; - page.setAttribute('data-firstload', '1'); } if (delay) { setTimeout(function () { - LibraryBrowser.onTabbedpagebeforeshowInternal(page, e, isFirstLoad); + LibraryBrowser.onTabbedpagebeforeshowInternal(page, e); }, delay); } else { - LibraryBrowser.onTabbedpagebeforeshowInternal(page, e, isFirstLoad); + LibraryBrowser.onTabbedpagebeforeshowInternal(page, e); } }, - onTabbedpagebeforeshowInternal: function (page, e, isFirstLoad) { + onTabbedpagebeforeshowInternal: function (page, e) { var pageTabsContainer = page.querySelector('.libraryViewNav'); - if (isFirstLoad) { - - console.log('selected tab is null, checking query string'); - - var selected = page.firstTabIndex != null ? page.firstTabIndex : parseInt(getParameterByName('tab') || '0'); - - console.log('selected tab will be ' + selected); - - LibraryBrowser.selectedTab(pageTabsContainer, selected); - - } else { - - // Go back to the first tab - if (!e.detail.isRestored) { - LibraryBrowser.selectedTab(pageTabsContainer, 0); - return; - } - pageTabsContainer.dispatchEvent(new CustomEvent("beforetabchange", { - detail: { - selectedTabIndex: LibraryBrowser.selectedTab(pageTabsContainer) - } - })); - pageTabsContainer.dispatchEvent(new CustomEvent("tabchange", { - detail: { - selectedTabIndex: LibraryBrowser.selectedTab(pageTabsContainer) - } - })); + // Go back to the first tab + if (!e.detail.isRestored) { + pageTabsContainer.selectedIndex(0); + return; } + pageTabsContainer.triggerTabChange(); }, showTab: function (url, index) { @@ -814,7 +678,7 @@ document.body.appendChild(dlg); // Seeing an issue in Firefox and IE where it's initially visible in the bottom right, then moves to the center - var delay = browserInfo.animate ? 0 : 100; + var delay = browser.animate ? 0 : 100; setTimeout(function () { dialogHelper.open(dlg); }, delay); diff --git a/dashboard-ui/scripts/librarymenu.js b/dashboard-ui/scripts/librarymenu.js index 0a4865086c..b24afda042 100644 --- a/dashboard-ui/scripts/librarymenu.js +++ b/dashboard-ui/scripts/librarymenu.js @@ -645,32 +645,30 @@ viewMenuBarTabs.classList.remove('hide'); } - if (LibraryMenu.tabType != type) { + require(['emby-tabs', 'emby-button'], function () { + if (LibraryMenu.tabType != type) { - var index = 0; + var index = 0; - viewMenuBarTabs.innerHTML = '
' + builder().map(function (t) { + viewMenuBarTabs.innerHTML = '
' + builder().map(function (t) { - var tabClass = selectedIndex == index ? 'pageTabButton is-active' : 'pageTabButton'; + var tabClass = selectedIndex == index ? 'emby-tab-button emby-tab-button-active' : 'emby-tab-button'; - var tabHtml = '' + t.name + '
'; - index++; - return tabHtml; + var tabHtml = ''; + index++; + return tabHtml; - }).join('') + '
'; + }).join('') + '
'; - document.body.classList.add('withTallToolbar'); + document.body.classList.add('withTallToolbar'); + LibraryMenu.tabType = type; + return; + } + + viewMenuBarTabs.querySelector('is=["emby-tabs"]').selectedIndex(selectedIndex); + LibraryMenu.tabType = type; - return; - } - - 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; + }); }, setTitle: function (title) { diff --git a/dashboard-ui/scripts/livetvsuggested.js b/dashboard-ui/scripts/livetvsuggested.js index 198080aa36..56fadd3220 100644 --- a/dashboard-ui/scripts/livetvsuggested.js +++ b/dashboard-ui/scripts/livetvsuggested.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'cardBuilder', 'scrollStyles', 'emby-itemscontainer'], function (libraryBrowser, cardBuilder) { +define(['libraryBrowser', 'cardBuilder', 'scrollStyles', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (libraryBrowser, cardBuilder) { function enableScrollX() { return browserInfo.mobile && AppInfo.enableAppLayouts; diff --git a/dashboard-ui/scripts/moviesrecommended.js b/dashboard-ui/scripts/moviesrecommended.js index de8257c886..02723d9b2d 100644 --- a/dashboard-ui/scripts/moviesrecommended.js +++ b/dashboard-ui/scripts/moviesrecommended.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'components/categorysyncbuttons', 'cardBuilder', 'scrollStyles', 'emby-itemscontainer'], function (libraryBrowser, categorysyncbuttons, cardBuilder) { +define(['libraryBrowser', 'components/categorysyncbuttons', 'cardBuilder', 'scrollStyles', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (libraryBrowser, categorysyncbuttons, cardBuilder) { function enableScrollX() { return browserInfo.mobile && AppInfo.enableAppLayouts; @@ -323,11 +323,7 @@ if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') { renderedTabs = []; - mdlTabs.dispatchEvent(new CustomEvent("tabchange", { - detail: { - selectedTabIndex: libraryBrowser.selectedTab(mdlTabs) - } - })); + mdlTabs.triggerTabChange(); } } diff --git a/dashboard-ui/scripts/musicrecommended.js b/dashboard-ui/scripts/musicrecommended.js index 5de0a0777e..70bbc97c91 100644 --- a/dashboard-ui/scripts/musicrecommended.js +++ b/dashboard-ui/scripts/musicrecommended.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'cardBuilder', 'scrollStyles', 'emby-itemscontainer'], function (libraryBrowser, cardBuilder) { +define(['libraryBrowser', 'cardBuilder', 'scrollStyles', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (libraryBrowser, cardBuilder) { function itemsPerRow() { diff --git a/dashboard-ui/scripts/nowplayingpage.js b/dashboard-ui/scripts/nowplayingpage.js index 394d002ae2..768efcb71e 100644 --- a/dashboard-ui/scripts/nowplayingpage.js +++ b/dashboard-ui/scripts/nowplayingpage.js @@ -1,4 +1,4 @@ -define(['components/remotecontrol'], function (remotecontrolFactory) { +define(['components/remotecontrol', 'emby-tabs', 'emby-button'], function (remotecontrolFactory) { return function (view, params) { diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 5493bbce45..ef37036304 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -1268,6 +1268,7 @@ var AppInfo = {}; define("emby-collapse", [embyWebComponentsBowerPath + "/emby-collapse/emby-collapse"], returnFirstDependency); define("emby-button", [embyWebComponentsBowerPath + "/emby-button/emby-button"], returnFirstDependency); define("emby-itemscontainer", [embyWebComponentsBowerPath + "/emby-itemscontainer/emby-itemscontainer"], returnFirstDependency); + define("emby-tabs", [embyWebComponentsBowerPath + "/emby-tabs/emby-tabs"], returnFirstDependency); define("itemHoverMenu", [embyWebComponentsBowerPath + "/itemhovermenu/itemhovermenu"], returnFirstDependency); define("multiSelect", [embyWebComponentsBowerPath + "/multiselect/multiselect"], returnFirstDependency); define("alphaPicker", [embyWebComponentsBowerPath + "/alphapicker/alphapicker"], returnFirstDependency); diff --git a/dashboard-ui/scripts/tvrecommended.js b/dashboard-ui/scripts/tvrecommended.js index 46689b7063..c493353940 100644 --- a/dashboard-ui/scripts/tvrecommended.js +++ b/dashboard-ui/scripts/tvrecommended.js @@ -1,4 +1,4 @@ -define(['libraryBrowser', 'components/categorysyncbuttons', 'cardBuilder', 'scrollStyles', 'emby-itemscontainer'], function (libraryBrowser, categorysyncbuttons, cardBuilder) { +define(['libraryBrowser', 'components/categorysyncbuttons', 'cardBuilder', 'scrollStyles', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (libraryBrowser, categorysyncbuttons, cardBuilder) { return function (view, params) { @@ -209,11 +209,7 @@ if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') { renderedTabs = []; - mdlTabs.dispatchEvent(new CustomEvent("tabchange", { - detail: { - selectedTabIndex: libraryBrowser.selectedTab(mdlTabs) - } - })); + mdlTabs.triggerTabChange(); } } diff --git a/dashboard-ui/tv.html b/dashboard-ui/tv.html index b4d99d8007..23560a8784 100644 --- a/dashboard-ui/tv.html +++ b/dashboard-ui/tv.html @@ -1,14 +1,28 @@ 
-
-
- - - - - - - +
+
+ + + + + + +