diff --git a/dashboard-ui/apiclient/apiclient.js b/dashboard-ui/apiclient/apiclient.js index 09a2d5a0e..7c4c7e94d 100644 --- a/dashboard-ui/apiclient/apiclient.js +++ b/dashboard-ui/apiclient/apiclient.js @@ -295,6 +295,9 @@ // http://api.jquery.com/jQuery.ajax/ if (enableReconnection && !isUserErrorCode) { + + logger.log("Attempting reconnection"); + tryReconnect().done(function () { logger.log("Reconnect succeesed"); @@ -309,6 +312,8 @@ }); } else { + logger.log("Reporting request failure"); + onRetryRequestFail(request); deferred.reject(); } diff --git a/dashboard-ui/css/librarybrowser.css b/dashboard-ui/css/librarybrowser.css index 60db3ffa3..b191f1992 100644 --- a/dashboard-ui/css/librarybrowser.css +++ b/dashboard-ui/css/librarybrowser.css @@ -12,16 +12,33 @@ margin-left: .5em; } -.backdropPage.ui-page-theme-a { +.pageWithAbsoluteTabs { + background-color: transparent !important; +} + +.backdropPage.ui-page-theme-a:not(.pageWithAbsoluteTabs) { background-color: rgba(240, 240,240, .94) !important; } -.ui-page-theme-b { - background-color: #1f1f1f; +.backdropPage.ui-page-theme-b:not(.pageWithAbsoluteTabs), .backdropPage.pageWithAbsoluteTabs .pageBackground { + background-color: rgba(20, 20,20, .92) !important; } -.backdropPage.ui-page-theme-b { - background-color: rgba(20, 20,20, .92) !important; +.pageWithAbsoluteTabs .pageBackground { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1; +} + +.pageWithAbsoluteTabs neon-animatable { + z-index: 2; +} + +.ui-page-theme-b:not(.pageWithAbsoluteTabs), .pageWithAbsoluteTabs .pageBackground { + background-color: #1f1f1f; } .backdropContainer { diff --git a/dashboard-ui/css/librarymenu.css b/dashboard-ui/css/librarymenu.css index b0a7394c4..6d39e7681 100644 --- a/dashboard-ui/css/librarymenu.css +++ b/dashboard-ui/css/librarymenu.css @@ -253,12 +253,12 @@ background-color: #212121; } -.libraryViewNav .ui-btn-active { +.libraryViewNav:not(.paperLibraryViewNav) .ui-btn-active { border-bottom-color: #38c; color: #fff !important; } -.libraryViewNav a { +.libraryViewNav:not(.paperLibraryViewNav) a { display: inline-block; padding: 14px 13px 11px; color: rgba(255,255,255,.8) !important; @@ -269,9 +269,35 @@ border-bottom: 5px solid transparent; } - .libraryViewNav a:not(.ui-btn-active):hover { - color: #2ad !important; - } +.paperLibraryViewNav a { + color: #ddd !important; + text-decoration: none; + text-align: center; + vertical-align: middle; + line-height: 48px; +} + +.paperLibraryViewNav .iron-selected a { + color: inherit !important; + text-decoration: none; + text-align: center; +} + +.basicPaperLibraryTabs .libraryViewNav .tab-content { + border-bottom: 6px solid transparent; +} + +.basicPaperLibraryTabs .libraryViewNav .iron-selected .tab-content { + border-bottom: 6px solid #38c; +} + +.basicPaperLibraryTabs .libraryViewNav paper-tabs { + display: none; +} + +.libraryViewNav:not(.paperLibraryViewNav) a:not(.ui-btn-active):hover { + color: #2ad !important; +} @media all and (max-width: 500px) { diff --git a/dashboard-ui/css/nowplayingbar.css b/dashboard-ui/css/nowplayingbar.css index 4bf02129c..336cc514a 100644 --- a/dashboard-ui/css/nowplayingbar.css +++ b/dashboard-ui/css/nowplayingbar.css @@ -15,11 +15,6 @@ margin: 0; text-align: center; } - -.nowPlayingBar paper-icon-button.mediaButton { - padding: 4px; -} - .mediaButton iron-icon { height: 40px; width: 40px; @@ -100,7 +95,7 @@ .nowPlayingBarCenter { vertical-align: middle; text-align: center; - margin-top: 20px; + margin-top: 17px; } .nowPlayingBarPositionContainer { @@ -143,7 +138,7 @@ .nowPlayingBarRight { position: absolute; - bottom: 22px; + bottom: 17px; right: 10px; vertical-align: middle; } @@ -156,7 +151,7 @@ vertical-align: middle; font-weight: normal; position: absolute; - bottom: 38px; + bottom: 36px; text-align: center; display: inline-block; margin: 0 auto; @@ -174,7 +169,7 @@ } -@media all and (max-width: 1200px) { +@media all and (max-width: 1300px) { .nowPlayingBarUserDataButtons { display: none; @@ -192,14 +187,16 @@ } .nowPlayingBarRight { - bottom: 26px; + bottom: 22px; } } @media all and (max-width: 800px) { .nowPlayingBarCurrentTime { - display: none; + padding-left: 0; + bottom: 30px; + right: 130px; } .nowPlayingBarCenter > *:not(.nowPlayingBarCurrentTime) { @@ -207,7 +204,7 @@ } .nowPlayingBarRight { - bottom: 12px; + bottom: 10px; } .nowPlayingBar, .nowPlayingImage img { @@ -237,3 +234,10 @@ display: none; } } + +@media all and (max-width: 600px) { + + .nowPlayingBarCurrentTime { + display: none; + } +} diff --git a/dashboard-ui/css/site.css b/dashboard-ui/css/site.css index b88e17708..edd668c70 100644 --- a/dashboard-ui/css/site.css +++ b/dashboard-ui/css/site.css @@ -312,6 +312,8 @@ html { body { overflow-y: scroll !important; + /* This is needed to prevent a horizontal scrollbar while neon-animated-pages are animating. */ + overflow-x: hidden; font-size: 13px; font-family: Roboto, Arial, Helvetica, sans-serif; /*Can't use this with safari or it causes some content to disappear*/ @@ -330,6 +332,11 @@ body { background-color: transparent !important; } +/* Undo this from jqm which may cause the page to have it's own scrollbar */ +.ui-mobile .ui-page-active { + overflow-x: visible; +} + .bodyWithPopupOpen { overflow-y: hidden !important; } @@ -752,7 +759,7 @@ h1 .imageLink { margin-bottom: 30px !important; } -.page > .ui-content { +.page > .ui-content, .pageWithAbsoluteTabs .pageTabContent { /* Need this so that the audio player doesn't cover content, but also for unveil lazy loading. */ padding-bottom: 160px; } diff --git a/dashboard-ui/homefavorites.html b/dashboard-ui/homefavorites.html deleted file mode 100644 index ddc192b73..000000000 --- a/dashboard-ui/homefavorites.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - Emby - - -
- -
- home${TabHome} - navigate_next${TabNextUp} - favorite${TabFavorites} - schedule${TabUpcoming} -
- -
- -
-
-
-
-
- - diff --git a/dashboard-ui/homenextup.html b/dashboard-ui/homenextup.html deleted file mode 100644 index 10b2b3b9e..000000000 --- a/dashboard-ui/homenextup.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - Emby - - -
- - -
-
- - - -
-
-

${HeaderNextUp}

- ${ButtonSync} -
-
-
-
- -
-
-
- - diff --git a/dashboard-ui/homeupcoming.html b/dashboard-ui/homeupcoming.html deleted file mode 100644 index 1472c45d5..000000000 --- a/dashboard-ui/homeupcoming.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - Emby - - -
- -
-
-
-
- -
-
-
- - diff --git a/dashboard-ui/index.html b/dashboard-ui/index.html index 913d1e318..bff333ca5 100644 --- a/dashboard-ui/index.html +++ b/dashboard-ui/index.html @@ -5,28 +5,71 @@ -
+
-
- home${TabHome} - navigate_next${TabNextUp} - favorite${TabFavorites} - schedule${TabUpcoming} +
+ + home${TabHome} + navigate_next${TabNextUp} + favorite${TabFavorites} + schedule${TabUpcoming} + + +
+ + + +
+
+ + +
+
+
+
+ +
+
+
+

${HeaderNextUp}

+ ${ButtonSync} +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+
+
- - -
-
-
-
diff --git a/dashboard-ui/itemdetails.html b/dashboard-ui/itemdetails.html index 3ad53c90c..7c478a6da 100644 --- a/dashboard-ui/itemdetails.html +++ b/dashboard-ui/itemdetails.html @@ -9,9 +9,9 @@ diff --git a/dashboard-ui/scripts/favorites.js b/dashboard-ui/scripts/favorites.js index 8e73c8aad..edbd158c7 100644 --- a/dashboard-ui/scripts/favorites.js +++ b/dashboard-ui/scripts/favorites.js @@ -54,7 +54,7 @@ html += '
'; if (result.TotalRecordCount > result.Items.length) { - var href = "homefavorites.html?sectionid=" + section.id; + var href = "index.html?tab=2§ionid=" + section.id; html += '' + Globalize.translate('ButtonMoreItems') + ''; } @@ -113,15 +113,20 @@ }); } - $(document).on('pagebeforeshowready', "#favoritesPage", function () { + $(document).on('pageinitdepends', "#indexPage", function () { var page = this; + var tabContent = page.querySelector('.homeFavoritesTabContent'); - var userId = Dashboard.getCurrentUserId(); + $(page.querySelector('neon-animated-pages')).on('iron-select', function () { + + if (parseInt(this.selected) == 2) { + if (LibraryBrowser.needsRefresh(tabContent)) { + loadSections(tabContent, Dashboard.getCurrentUserId()); + } + } + }); - if (LibraryBrowser.needsRefresh(page)) { - loadSections(page, userId); - } }); })(jQuery, document); \ No newline at end of file diff --git a/dashboard-ui/scripts/homenextup.js b/dashboard-ui/scripts/homenextup.js index 90540f2d4..088b51ae0 100644 --- a/dashboard-ui/scripts/homenextup.js +++ b/dashboard-ui/scripts/homenextup.js @@ -5,33 +5,11 @@ return 'Thumb'; } - function getResumeView() { - - return 'Poster'; - } - function reload(page) { Dashboard.showLoadingMsg(); - var context = ''; - - if (LibraryMenu.getTopParentId()) { - - $('.scopedLibraryViewNav', page).show(); - $('.globalNav', page).hide(); - $('.scopedContent', page).show(); - context = 'tv'; - - loadResume(page); - - } else { - $('.scopedLibraryViewNav', page).hide(); - $('.globalNav', page).show(); - $('.scopedContent', page).hide(); - } - - loadNextUp(page, context || 'home-nextup'); + loadNextUp(page, 'home-nextup'); } function loadNextUp(page, context) { @@ -55,11 +33,10 @@ ApiClient.getNextUpEpisodes(query).done(function (result) { if (result.Items.length) { - $('.noNextUpItems', page).hide(); + page.querySelector('.noNextUpItems').classList.add('hide'); } else { - $('.noNextUpItems', page).show(); + page.querySelector('.noNextUpItems').classList.remove('hide'); } - var view = getView(); var html = ''; @@ -101,95 +78,20 @@ }); } - function enableScrollX() { - return $.browser.mobile && AppInfo.enableAppLayouts; - } - - function getThumbShape() { - return enableScrollX() ? 'overflowBackdrop' : 'backdrop'; - } - - function loadResume(page) { - - var parentId = LibraryMenu.getTopParentId(); - - var screenWidth = $(window).width(); - - var limit = 6; - - var options = { - - SortBy: "DatePlayed", - SortOrder: "Descending", - IncludeItemTypes: "Episode", - Filters: "IsResumable", - Limit: limit, - Recursive: true, - Fields: "PrimaryImageAspectRatio,SeriesInfo,UserData,SyncInfo", - ExcludeLocationTypes: "Virtual", - ParentId: parentId, - ImageTypeLimit: 1, - EnableImageTypes: "Primary,Backdrop,Banner,Thumb" - }; - - ApiClient.getItems(Dashboard.getCurrentUserId(), options).done(function (result) { - - if (result.Items.length) { - $('#resumableSection', page).show(); - } else { - $('#resumableSection', page).hide(); - } - - var view = getResumeView(); - var html = ''; - - if (view == 'PosterCard') { - - html += LibraryBrowser.getPosterViewHtml({ - items: result.Items, - shape: getThumbShape(), - showTitle: true, - showParentTitle: true, - lazy: true, - cardLayout: true, - context: 'tv', - showDetailsMenu: true - }); - - } else if (view == 'Poster') { - - html += LibraryBrowser.getPosterViewHtml({ - items: result.Items, - shape: getThumbShape(), - showTitle: true, - showParentTitle: true, - overlayText: screenWidth >= 800 && !AppInfo.hasLowImageBandwidth, - lazy: true, - context: 'tv', - showDetailsMenu: true - }); - } - - var elem = page.querySelector('#resumableItems'); - elem.innerHTML = html; - ImageLoader.lazyChildren(elem); - }); - } - - $(document).on('pagebeforeshowready', "#homeNextUpPage", function () { + $(document).on('pageinitdepends', "#indexPage", function () { var page = this; + var tabContent = page.querySelector('.homeNextUpTabContent'); - if (enableScrollX()) { - page.querySelector('#resumableItems').classList.add('hiddenScrollX'); - } else { - page.querySelector('#resumableItems').classList.remove('hiddenScrollX'); - } + $(page.querySelector('neon-animated-pages')).on('iron-select', function () { + + if (parseInt(this.selected) == 1) { + if (LibraryBrowser.needsRefresh(tabContent)) { - if (LibraryBrowser.needsRefresh(page)) { - reload(page); - } + reload(tabContent); + } + } + }); }); - })(jQuery, document); \ No newline at end of file diff --git a/dashboard-ui/scripts/homeupcoming.js b/dashboard-ui/scripts/homeupcoming.js index 9b9bc1e44..03715738e 100644 --- a/dashboard-ui/scripts/homeupcoming.js +++ b/dashboard-ui/scripts/homeupcoming.js @@ -59,14 +59,19 @@ }); } - $(document).on('pagebeforeshowready', "#homeUpcomingPage", function () { + $(document).on('pageinitdepends', "#indexPage", function () { var page = this; + var tabContent = page.querySelector('.homeUpcomingTabContent'); - if (LibraryBrowser.needsRefresh(page)) { - loadUpcoming(page); - } + $(page.querySelector('neon-animated-pages')).on('iron-select', function () { + + if (parseInt(this.selected) == 3) { + if (LibraryBrowser.needsRefresh(tabContent)) { + loadUpcoming(tabContent); + } + } + }); }); - })(jQuery, document); \ No newline at end of file diff --git a/dashboard-ui/scripts/indexpage.js b/dashboard-ui/scripts/indexpage.js index c0892fe9a..3d6e70f8a 100644 --- a/dashboard-ui/scripts/indexpage.js +++ b/dashboard-ui/scripts/indexpage.js @@ -164,19 +164,11 @@ }); } - $(document).on('pageinitdepends', "#indexPage", function () { + function loadHomeTab(page) { - var page = this; + var tabContent = page.querySelector('.homeTabContent'); - Events.on(page.querySelector('.btnTakeTour'), 'click', function () { - takeTour(page, Dashboard.getCurrentUserId()); - }); - - }).on('pagebeforeshowready', "#indexPage", function () { - - var page = this; - - if (LibraryBrowser.needsRefresh(page)) { + if (LibraryBrowser.needsRefresh(tabContent)) { if (window.ApiClient) { var userId = Dashboard.getCurrentUserId(); @@ -186,20 +178,76 @@ Dashboard.getCurrentUser().done(function (user) { - loadSections(page, user, result).done(function () { + loadSections(tabContent, user, result).done(function () { if (!AppInfo.isNativeApp) { showWelcomeIfNeeded(page, result); } Dashboard.hideLoadingMsg(); - LibraryBrowser.setLastRefreshed(page); + LibraryBrowser.setLastRefreshed(tabContent); }); }); }); } } + } + + function loadTab(page, index) { + + switch (index) { + + case 0: + loadHomeTab(page); + break; + default: + break; + } + } + + $(document).on('pageinitdepends', "#indexPage", function () { + + var page = this; + + Events.on(page.querySelector('.btnTakeTour'), 'click', function () { + takeTour(page, Dashboard.getCurrentUserId()); + }); + + var tabs = page.querySelector('paper-tabs'); + LibraryBrowser.configurePaperLibraryTabs(page, page.querySelectorAll('paper-tabs')[0], page.querySelectorAll('neon-animated-pages')[0]); + + $(tabs).on('iron-select', function () { + var selected = this.selected; + if (LibraryBrowser.navigateOnLibraryTabSelect()) { + + if (selected) { + Dashboard.navigate('index.html?tab=' + selected); + } else { + Dashboard.navigate('index.html'); + } + + } else { + page.querySelector('neon-animated-pages').selected = selected; + } + }); + + $(page.querySelector('neon-animated-pages')).on('iron-select', function () { + loadTab(page, parseInt(this.selected)); + }); + + }).on('pagebeforeshowready', "#indexPage", function () { + + var page = this; + + var tabs = page.querySelector('paper-tabs'); + var selected = tabs.selected; + + if (selected == null) { + selected = parseInt(getParameterByName('tab') || '0'); + tabs.selected = selected; + page.querySelector('neon-animated-pages').selected = selected; + } }); function getDisplayPreferencesAppName() { diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index 3402e0c68..a29846022 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -112,6 +112,87 @@ elem.classList.add('hasrefreshtime'); }, + configureSwipeTabs: function (ownerpage, tabs, pages) { + + var pageCount = pages.querySelectorAll('neon-animatable').length; + + function allowSwipe(e) { + + var target = e.target; + + if (target.classList.contains('noSwipe')) { + return false; + } + if ($(target).parents('.noSwipe').length) { + return false; + } + + return true; + } + + $(ownerpage).on('swipeleft', function (e) { + + if (allowSwipe(e)) { + var selected = parseInt(pages.selected || '0'); + if (selected < (pageCount - 1)) { + pages.entryAnimation = 'slide-from-right-animation'; + pages.exitAnimation = 'slide-left-animation'; + tabs.selectNext(); + } + } + }); + + $(ownerpage).on('swiperight', function (e) { + + if (allowSwipe(e)) { + var selected = parseInt(pages.selected || '0'); + if (selected > 0) { + pages.entryAnimation = 'slide-from-left-animation'; + pages.exitAnimation = 'slide-right-animation'; + tabs.selectPrevious(); + } + } + }); + }, + + enableFullPaperTabs: function () { + return AppInfo.isNativeApp; + }, + + navigateOnLibraryTabSelect: function () { + return !LibraryBrowser.enableFullPaperTabs(); + }, + + configurePaperLibraryTabs: function (ownerpage, tabs, pages) { + + tabs.hideScrollButtons = true; + + if (LibraryBrowser.enableFullPaperTabs()) { + + $(tabs).show(); + + LibraryBrowser.configureSwipeTabs(ownerpage, tabs, pages); + + $('.libraryViewNav', ownerpage).addClass('paperLibraryViewNav'); + + } else { + + tabs.noSlide = true; + tabs.noink = true; + tabs.noBar = true; + tabs.scrollable = true; + + var legacyTabs = $('.legacyTabs', ownerpage).show(); + document.body.classList.add('basicPaperLibraryTabs'); + + $(pages).on('iron-select', function (e) { + + var selected = this.selected; + $('a', legacyTabs).removeClass('ui-btn-active')[selected].classList.add('ui-btn-active'); + }); + } + }, + getDateParamValue: function (date) { function formatDigit(i) { diff --git a/dashboard-ui/scripts/nowplayingpage.js b/dashboard-ui/scripts/nowplayingpage.js index 2732a36d2..dbda6a62d 100644 --- a/dashboard-ui/scripts/nowplayingpage.js +++ b/dashboard-ui/scripts/nowplayingpage.js @@ -713,20 +713,6 @@ } } - function allowSwipe(e) { - - var target = $(e.target); - - if (target.is('.noSwipe')) { - return false; - } - if (target.parents('.noSwipe').length) { - return false; - } - - return true; - } - function onPlayerChange() { bindToPlayer($($.mobile.activePage)[0], MediaController.getCurrentPlayer()); } @@ -742,42 +728,14 @@ $('.requiresJqmCreate', this).trigger('create'); - $(page).on('swipeleft', function (e) { - - if (allowSwipe(e)) { - var pages = this.querySelectorAll('neon-animated-pages')[0]; - var tabs = this.querySelectorAll('paper-tabs')[0]; - - var selected = parseInt(pages.selected || '0'); - if (selected < 2) { - pages.entryAnimation = 'slide-from-right-animation'; - pages.exitAnimation = 'slide-left-animation'; - tabs.selectNext(); - } - } - }); - - $(page).on('swiperight', function (e) { - - if (allowSwipe(e)) { - var pages = this.querySelectorAll('neon-animated-pages')[0]; - var tabs = this.querySelectorAll('paper-tabs')[0]; - - var selected = parseInt(pages.selected || '0'); - if (selected > 0) { - pages.entryAnimation = 'slide-from-left-animation'; - pages.exitAnimation = 'slide-right-animation'; - tabs.selectPrevious(); - } - } - }); + LibraryBrowser.configureSwipeTabs(page, page.querySelectorAll('paper-tabs')[0], page.querySelectorAll('neon-animated-pages')[0]); $(MediaController).on('playerchange', function () { updateCastIcon(page); }); $('paper-tabs').on('iron-select', function () { - page.querySelectorAll('neon-animated-pages')[0].selected = this.selected; + page.querySelector('neon-animated-pages').selected = this.selected; }); }).on('pagebeforeshowready', "#nowPlayingPage", function () { diff --git a/dashboard-ui/scripts/sections.js b/dashboard-ui/scripts/sections.js index 1c722035d..be88c415a 100644 --- a/dashboard-ui/scripts/sections.js +++ b/dashboard-ui/scripts/sections.js @@ -305,7 +305,7 @@ if (result.Items.length) { html += '

' + Globalize.translate('HeaderResume') + '

'; if (enableScrollX()) { - html += '
'; + html += '
'; } else { html += '
'; } diff --git a/dashboard-ui/thirdparty/paper-button-style.css b/dashboard-ui/thirdparty/paper-button-style.css index 2316dc8b1..62422a9a6 100644 --- a/dashboard-ui/thirdparty/paper-button-style.css +++ b/dashboard-ui/thirdparty/paper-button-style.css @@ -266,6 +266,7 @@ paper-tabs, paper-toolbar { paper-tab { text-transform: uppercase; + font-weight: 400; } paper-tabs:not([alignbottom]) #selectionBar {