diff --git a/dashboard-ui/connectlogin.html b/dashboard-ui/connectlogin.html index 476f81b073..92e870334e 100644 --- a/dashboard-ui/connectlogin.html +++ b/dashboard-ui/connectlogin.html @@ -29,7 +29,7 @@ -

${ButtonForgotPassword}

- diff --git a/dashboard-ui/index.html b/dashboard-ui/index.html index d023a56c4e..35870c5c08 100644 --- a/dashboard-ui/index.html +++ b/dashboard-ui/index.html @@ -10,7 +10,7 @@ ${TabHome} ${TabLatest} ${TabNextUp} - ${TabFavorites} + ${TabFavorites} ${TabUpcoming} diff --git a/dashboard-ui/itemdetails.html b/dashboard-ui/itemdetails.html index a138b34758..dae4b84877 100644 --- a/dashboard-ui/itemdetails.html +++ b/dashboard-ui/itemdetails.html @@ -10,7 +10,7 @@
${TabHome} ${TabLatest} - ${TabNextUp} + ${TabNextUp} ${TabFavorites} ${TabUpcoming}
diff --git a/dashboard-ui/scripts/backdrops.js b/dashboard-ui/scripts/backdrops.js index f0909de740..479f9303eb 100644 --- a/dashboard-ui/scripts/backdrops.js +++ b/dashboard-ui/scripts/backdrops.js @@ -97,6 +97,19 @@ }); } + function setDefault(page) { + + var backdropContainer = $('.backdropContainer'); + + if (backdropContainer.length) { + backdropContainer.css('backgroundImage', 'url(css/images/splash.jpg)'); + } else { + $(document.body).prepend('
'); + } + + $(page).addClass('backdropPage staticBackdropPage'); + } + function clearBackdrop() { $('.backdropContainer').css('backgroundImage', ''); @@ -213,7 +226,8 @@ window.Backdrops = { setBackdrops: setBackdrops, - setBackdropUrl: setBackdropUrl + setBackdropUrl: setBackdropUrl, + setDefault: setDefault }; })(jQuery, document); \ No newline at end of file diff --git a/dashboard-ui/scripts/channelitems.js b/dashboard-ui/scripts/channelitems.js index 2dfecc854a..cd0b70c4be 100644 --- a/dashboard-ui/scripts/channelitems.js +++ b/dashboard-ui/scripts/channelitems.js @@ -146,8 +146,10 @@ defaultShape: 'square', context: 'channels', showTitle: true, - centerText: true, - coverImage: true + coverImage: true, + cardLayout: true, + showYear: true, + lazy: true }); var elem = $('#items', page).html(html).lazyChildren(); diff --git a/dashboard-ui/scripts/channels.js b/dashboard-ui/scripts/channels.js index 46b24a87ca..b3b3cc65fa 100644 --- a/dashboard-ui/scripts/channels.js +++ b/dashboard-ui/scripts/channels.js @@ -21,14 +21,32 @@ updateFilterControls(page); - html = LibraryBrowser.getPosterViewHtml({ - items: result.Items, - shape: "backdrop", - context: 'channels', - showTitle: true, - centerText: true, - preferThumb: true - }); + var view = 'Thumb'; + + if (view == "Thumb") { + + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "backdrop", + context: 'channels', + showTitle: true, + centerText: true, + preferThumb: true + }); + + } + else if (view == "ThumbCard") { + + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "backdrop", + preferThumb: true, + context: 'channels', + lazy: true, + cardLayout: true, + showTitle: true + }); + } $('#items', page).html(html).lazyChildren(); diff --git a/dashboard-ui/scripts/connectlogin.js b/dashboard-ui/scripts/connectlogin.js index 7cd0682898..a4172197f8 100644 --- a/dashboard-ui/scripts/connectlogin.js +++ b/dashboard-ui/scripts/connectlogin.js @@ -2,12 +2,13 @@ function onLoggedIn() { + Dashboard.hideModalLoadingMsg(); Dashboard.navigate('selectserver.html'); } function login(page, username, password) { - Dashboard.showLoadingMsg(); + Dashboard.showModalLoadingMsg(); ConnectionManager.loginToConnect(username, password).done(function () { @@ -30,6 +31,8 @@ function handleConnectionResult(page, result) { + Dashboard.hideLoadingMsg(); + switch (result.State) { case MediaBrowser.ConnectionState.SignedIn: @@ -71,12 +74,10 @@ function loadAppConnection(page) { - Dashboard.showLoadingMsg(); + Dashboard.showModalLoadingMsg(); ConnectionManager.connect().done(function (result) { - Dashboard.hideLoadingMsg(); - handleConnectionResult(page, result); }); @@ -99,8 +100,7 @@ } function loadMode(page, mode) { - $(document.body).prepend('
'); - $(page).addClass('backdropPage staticBackdropPage'); + Backdrops.setDefault(page); if (mode == 'welcome') { $('.connectLoginForm', page).hide(); @@ -119,13 +119,17 @@ } } + function skip() { + + Dashboard.navigate('selectserver.html'); + } + $(document).on('pageinit', "#connectLoginPage", function () { var page = this; - $('.btnSkipConnect', page).on('click', function() { - - Dashboard.navigate('connectlogin.html?mode=manualserver'); + $('.btnSkipConnect', page).on('click', function () { + skip(); }); }).on('pageshow', "#connectLoginPage", function () { @@ -138,13 +142,9 @@ $('.embyIntroDownloadMessage', page).html(Globalize.translate('EmbyIntroDownloadMessage', link)); if (Dashboard.isRunningInCordova()) { - $('.newUsers', page).hide(); - $('.forgotPassword', page).hide(); $('.skip', page).show(); } else { $('.skip', page).hide(); - $('.newUsers', page).show(); - $('.forgotPassword', page).show(); } }); @@ -157,18 +157,14 @@ host += ':' + port; } - Dashboard.showLoadingMsg(); + Dashboard.showModalLoadingMsg(); ConnectionManager.connectToAddress(host).done(function (result) { - Dashboard.hideLoadingMsg(); - handleConnectionResult(page, result); }).fail(function () { - Dashboard.hideLoadingMsg(); - handleConnectionResult(page, { State: MediaBrowser.ConnectionState.Unavailable }); diff --git a/dashboard-ui/scripts/dashboardpage.js b/dashboard-ui/scripts/dashboardpage.js index 0f7cd47462..d2048f0ae7 100644 --- a/dashboard-ui/scripts/dashboardpage.js +++ b/dashboard-ui/scripts/dashboardpage.js @@ -626,7 +626,7 @@ imgUrl = 'css/images/clients/html5.png'; } - return "Emby Web Client"; + return "Emby Mobile"; } if (clientLowered == "mb-classic") { diff --git a/dashboard-ui/scripts/episodes.js b/dashboard-ui/scripts/episodes.js index 1a8b325cc4..d7559f18d6 100644 --- a/dashboard-ui/scripts/episodes.js +++ b/dashboard-ui/scripts/episodes.js @@ -1,6 +1,6 @@ (function ($, document) { - var view = LibraryBrowser.getDefaultItemsView('Poster', 'Poster'); + var view = LibraryBrowser.getDefaultItemsView('Poster', 'PosterCard'); // The base query options var query = { @@ -46,6 +46,12 @@ updateFilterControls(); var trigger = false; + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Poster') { + view = 'PosterCard'; + } + } + if (view == "List") { html = LibraryBrowser.getListViewHtml({ diff --git a/dashboard-ui/scripts/indexpage.js b/dashboard-ui/scripts/indexpage.js index 65a47b5bae..7a4c8e228c 100644 --- a/dashboard-ui/scripts/indexpage.js +++ b/dashboard-ui/scripts/indexpage.js @@ -139,6 +139,8 @@ var html = ''; + var cardLayout = AppInfo.hasLowImageBandwidth; + if (items.length) { html += '
'; html += '

' + Globalize.translate('HeaderLatestMedia') + '

'; @@ -157,6 +159,9 @@ showUnplayedIndicator: false, showChildCountIndicator: true, lazy: true, + cardLayout: cardLayout, + showTitle: cardLayout, + showYear: cardLayout }); html += '
'; } @@ -275,6 +280,8 @@ var html = ''; + var cardLayout = AppInfo.hasLowImageBandwidth; + if (result.Items.length) { html += '

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

'; html += '
'; @@ -282,11 +289,12 @@ items: result.Items, preferThumb: true, shape: 'backdrop', - overlayText: screenWidth >= 800 && !AppInfo.hasLowImageBandwidth, + overlayText: screenWidth >= 800 && !cardLayout, showTitle: true, showParentTitle: true, context: 'home', - lazy: true + lazy: true, + cardLayout: cardLayout }); html += '
'; } @@ -542,10 +550,10 @@ function dismissWelcome(page, userId) { - ApiClient.getDisplayPreferences('home', userId, 'webclient').done(function (result) { + getDisplayPreferences('home', userId).done(function (result) { result.CustomPrefs[homePageTourKey] = homePageDismissValue; - ApiClient.updateDisplayPreferences('home', result, userId, 'webclient'); + ApiClient.updateDisplayPreferences('home', result, userId, getDisplayPreferencesAppName()); }); } @@ -635,7 +643,7 @@ var userId = Dashboard.getCurrentUserId(); - ApiClient.getDisplayPreferences('home', userId, 'webclient').done(function (result) { + getDisplayPreferences('home', userId).done(function (result) { Dashboard.getCurrentUser().done(function (user) { @@ -648,4 +656,20 @@ }); + function getDisplayPreferencesAppName() { + + if (Dashboard.isRunningInCordova()) { + return 'Emby Mobile'; + } + + return 'webclient'; + } + + function getDisplayPreferences(key, userId) { + + return ApiClient.getDisplayPreferences(key, userId, getDisplayPreferencesAppName()).done(function (result) { + + }); + } + })(jQuery, document); diff --git a/dashboard-ui/scripts/itemdetailpage.js b/dashboard-ui/scripts/itemdetailpage.js index c834b99069..7590b125d0 100644 --- a/dashboard-ui/scripts/itemdetailpage.js +++ b/dashboard-ui/scripts/itemdetailpage.js @@ -342,7 +342,7 @@ var chapters = item.Chapters || []; - if (!chapters.length) { + if (!chapters.length || AppInfo.hasLowImageBandwidth) { $('#scenesCollapsible', page).hide(); } else { $('#scenesCollapsible', page).show(); @@ -616,9 +616,11 @@ var promise; + var screenWidth = $(window).width(); + var options = { userId: Dashboard.getCurrentUserId(), - limit: 5, + limit: screenWidth > 800 ? 5 : 4, fields: "PrimaryImageAspectRatio,UserData,SyncInfo" }; diff --git a/dashboard-ui/scripts/itemlistpage.js b/dashboard-ui/scripts/itemlistpage.js index 15b236005a..1156b4f951 100644 --- a/dashboard-ui/scripts/itemlistpage.js +++ b/dashboard-ui/scripts/itemlistpage.js @@ -55,6 +55,12 @@ context = 'folders'; } + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Poster') { + view = 'PosterCard'; + } + } + if (view == "Backdrop") { html = LibraryBrowser.getPosterViewHtml({ @@ -75,6 +81,16 @@ context: context }); } + else if (view == "PosterCard") { + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "auto", + showTitle: true, + context: context, + cardLayout: true, + showYear: true + }); + } var elem = $('#items', page).html(html).lazyChildren(); diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index b51e69053d..af2bfc65c3 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -1006,9 +1006,7 @@ var imagesPerRow = LibraryBrowser.getPostersPerRow(screenWidth); - if (AppInfo.hasLowImageBandwidth) { - screenWidth *= .95; - } else { + if (!AppInfo.hasLowImageBandwidth) { screenWidth *= 1.25; } @@ -1565,7 +1563,8 @@ if (options.cardLayout) { html += '
'; // Render out the jqm classes so that we don't have to call trigger create - html += ''; + //html += ''; + html += ''; html += "
"; } @@ -1618,15 +1617,19 @@ lines.push(songLine); } - if (options.showPremiereDate && item.PremiereDate) { + if (options.showPremiereDate) { - try { + if (item.PremiereDate) { + try { - lines.push(LibraryBrowser.getPremiereDateText(item)); + lines.push(LibraryBrowser.getPremiereDateText(item)); - } catch (err) { + } catch (err) { + lines.push(''); + + } + } else { lines.push(''); - } } diff --git a/dashboard-ui/scripts/livetvchannels.js b/dashboard-ui/scripts/livetvchannels.js index 92b159ba6f..7b22ef26d8 100644 --- a/dashboard-ui/scripts/livetvchannels.js +++ b/dashboard-ui/scripts/livetvchannels.js @@ -11,7 +11,8 @@ return LibraryBrowser.getPosterViewHtml({ items: channels, shape: "smallBackdrop", - centerText: true + centerText: true, + lazy: true }); } diff --git a/dashboard-ui/scripts/moviecollections.js b/dashboard-ui/scripts/moviecollections.js index 5c030b07d7..178673bd0f 100644 --- a/dashboard-ui/scripts/moviecollections.js +++ b/dashboard-ui/scripts/moviecollections.js @@ -1,6 +1,6 @@ (function ($, document) { - var view = LibraryBrowser.getDefaultItemsView('Poster', 'Poster'); + var view = LibraryBrowser.getDefaultItemsView('Poster', 'PosterCard'); // The base query options var query = { @@ -53,6 +53,15 @@ updateFilterControls(page); var trigger = false; + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Thumb') { + view = 'ThumbCard'; + } + else if (view == 'Poster') { + view = 'PosterCard'; + } + } + if (result.TotalRecordCount) { if (view == "List") { @@ -74,6 +83,17 @@ lazy: true }); } + else if (view == "PosterCard") { + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "auto", + context: 'movies', + showTitle: true, + cardLayout: true, + lazy: true, + showItemCounts: true + }); + } else if (view == "Thumb") { html = LibraryBrowser.getPosterViewHtml({ items: result.Items, @@ -85,6 +105,18 @@ preferThumb: true }); } + else if (view == "ThumbCard") { + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "backdrop", + context: 'movies', + showTitle: true, + lazy: true, + preferThumb: true, + cardLayout: true, + showItemCounts: true + }); + } $('.noItemsMessage', page).hide(); diff --git a/dashboard-ui/scripts/moviegenres.js b/dashboard-ui/scripts/moviegenres.js index 902f5cd25a..bd269750a3 100644 --- a/dashboard-ui/scripts/moviegenres.js +++ b/dashboard-ui/scripts/moviegenres.js @@ -1,6 +1,6 @@ (function ($, document) { - var view = LibraryBrowser.getDefaultItemsView('Thumb', 'Thumb'); + var view = LibraryBrowser.getDefaultItemsView('Thumb', 'ThumbCard'); // The base query options var query = { @@ -39,6 +39,15 @@ updateFilterControls(page); + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Thumb') { + view = 'ThumbCard'; + } + else if (view == 'Poster') { + view = 'PosterCard'; + } + } + if (view == "Thumb") { html = LibraryBrowser.getPosterViewHtml({ items: result.Items, @@ -63,6 +72,17 @@ lazy: true }); } + else if (view == "PosterCard") { + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "portrait", + context: 'movies', + showItemCounts: true, + lazy: true, + cardLayout: true, + showTitle: true + }); + } else if (view == "Poster") { html = LibraryBrowser.getPosterViewHtml({ items: result.Items, diff --git a/dashboard-ui/scripts/movies.js b/dashboard-ui/scripts/movies.js index ef396db10f..061dbbf97a 100644 --- a/dashboard-ui/scripts/movies.js +++ b/dashboard-ui/scripts/movies.js @@ -1,6 +1,6 @@ (function ($, document) { - var view = LibraryBrowser.getDefaultItemsView('Poster', 'Poster'); + var view = LibraryBrowser.getDefaultItemsView('Poster', 'PosterCard'); // The base query options var query = { @@ -48,6 +48,15 @@ updateFilterControls(page); var trigger = false; + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Thumb') { + view = 'ThumbCard'; + } + else if (view == 'Poster') { + view = 'PosterCard'; + } + } + if (view == "Thumb") { html = LibraryBrowser.getPosterViewHtml({ items: result.Items, @@ -55,8 +64,7 @@ preferThumb: true, context: 'movies', lazy: true, - overlayText: true, - showTitle: false + overlayText: true }); } else if (view == "ThumbCard") { @@ -96,7 +104,6 @@ items: result.Items, shape: "portrait", context: 'movies', - showTitle: false, centerText: true, lazy: true, overlayText: true diff --git a/dashboard-ui/scripts/moviesrecommended.js b/dashboard-ui/scripts/moviesrecommended.js index 7aa56d39e2..b18e2271b9 100644 --- a/dashboard-ui/scripts/moviesrecommended.js +++ b/dashboard-ui/scripts/moviesrecommended.js @@ -1,10 +1,29 @@ (function ($, document) { + function getView() { + + if (AppInfo.hasLowImageBandwidth) { + return 'PosterCard'; + } + + return 'PosterCard'; + } + + function getResumeView() { + + if (AppInfo.hasLowImageBandwidth) { + return 'ThumbCard'; + } + + return 'ThumbCard'; + } + function loadLatest(page, userId, parentId) { - var limit = AppInfo.hasLowImageBandwidth ? - 15 : - 18; + var limit = 18; + if (AppInfo.hasLowImageBandwidth) { + limit = 10; + } var options = { @@ -18,13 +37,34 @@ ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)).done(function (items) { - $('#recentlyAddedItems', page).html(LibraryBrowser.getPosterViewHtml({ - items: items, - lazy: true, - shape: 'portrait', - overlayText: false + var view = getView(); + var html = ''; - })).lazyChildren().trigger('create'); + if (view == 'PosterCard') { + + html += LibraryBrowser.getPosterViewHtml({ + items: items, + lazy: true, + shape: 'portrait', + overlayText: false, + showTitle: true, + showYear: true, + cardLayout: true + + }); + + } else if (view == 'Poster') { + + html += LibraryBrowser.getPosterViewHtml({ + items: items, + shape: "portrait", + centerText: true, + lazy: true, + overlayText: true + }); + } + + $('#recentlyAddedItems', page).html(html).lazyChildren().trigger('create'); }); } @@ -55,15 +95,35 @@ $('#resumableSection', page).hide(); } - $('#resumableItems', page).html(LibraryBrowser.getPosterViewHtml({ - items: result.Items, - preferThumb: true, - shape: 'backdrop', - overlayText: true, - showTitle: true, - lazy: true + var view = getResumeView(); + var html = ''; - })).lazyChildren().trigger('create'); + if (view == 'ThumbCard') { + + html += LibraryBrowser.getPosterViewHtml({ + items: result.Items, + preferThumb: true, + shape: 'backdrop', + showTitle: true, + showYear: true, + lazy: true, + cardLayout: true + + }); + + } else if (view == 'Thumb') { + + html += LibraryBrowser.getPosterViewHtml({ + items: result.Items, + preferThumb: true, + shape: 'backdrop', + overlayText: true, + showTitle: true, + lazy: true + }); + } + + $('#resumableItems', page).html(html).lazyChildren().trigger('create'); }); } @@ -95,12 +155,32 @@ html += '

' + title + '

'; html += '
'; - html += LibraryBrowser.getPosterViewHtml({ - items: recommendation.Items, - lazy: true, - shape: 'portrait', - overlayText: true - }); + + var view = getView(); + + if (view == 'PosterCard') { + + html += LibraryBrowser.getPosterViewHtml({ + items: recommendation.Items, + lazy: true, + shape: 'portrait', + overlayText: false, + showTitle: true, + showYear: true, + cardLayout: true + + }); + + } else if (view == 'Poster') { + + html += LibraryBrowser.getPosterViewHtml({ + items: recommendation.Items, + shape: "portrait", + centerText: true, + lazy: true, + overlayText: true + }); + } html += '
'; return html; diff --git a/dashboard-ui/scripts/movietrailers.js b/dashboard-ui/scripts/movietrailers.js index 3b4859a8db..9b8925dd5b 100644 --- a/dashboard-ui/scripts/movietrailers.js +++ b/dashboard-ui/scripts/movietrailers.js @@ -1,6 +1,6 @@ (function ($, document) { - var view = LibraryBrowser.getDefaultItemsView('Poster', 'Poster'); + var view = LibraryBrowser.getDefaultItemsView('PosterCard', 'PosterCard'); // The base query options var query = { @@ -54,10 +54,10 @@ items: result.Items, shape: "portrait", context: 'movies-trailers', - showTitle: false, - centerText: true, + showTitle: true, + showYear: true, lazy: true, - overlayText: false + cardLayout: true }); var elem = $('.itemsContainer', page).html(html).lazyChildren(); diff --git a/dashboard-ui/scripts/musicalbumartists.js b/dashboard-ui/scripts/musicalbumartists.js index a19246fd41..ed35328792 100644 --- a/dashboard-ui/scripts/musicalbumartists.js +++ b/dashboard-ui/scripts/musicalbumartists.js @@ -46,6 +46,12 @@ updateFilterControls(page); var trigger = false; + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Poster') { + view = 'PosterCard'; + } + } + if (view == "List") { html = LibraryBrowser.getListViewHtml({ diff --git a/dashboard-ui/scripts/musicalbums.js b/dashboard-ui/scripts/musicalbums.js index 6e7e118420..c1c547e815 100644 --- a/dashboard-ui/scripts/musicalbums.js +++ b/dashboard-ui/scripts/musicalbums.js @@ -44,6 +44,12 @@ updateFilterControls(page); var trigger = false; + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Poster') { + view = 'PosterCard'; + } + } + if (view == "Poster") { html = LibraryBrowser.getPosterViewHtml({ items: result.Items, diff --git a/dashboard-ui/scripts/musicartists.js b/dashboard-ui/scripts/musicartists.js index 8c9171e84e..f04fb7507a 100644 --- a/dashboard-ui/scripts/musicartists.js +++ b/dashboard-ui/scripts/musicartists.js @@ -47,6 +47,12 @@ updateFilterControls(page); var trigger = false; + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Poster') { + view = 'PosterCard'; + } + } + if (view == "List") { html = LibraryBrowser.getListViewHtml({ diff --git a/dashboard-ui/scripts/musicgenres.js b/dashboard-ui/scripts/musicgenres.js index 70d0f1837c..210b8e9820 100644 --- a/dashboard-ui/scripts/musicgenres.js +++ b/dashboard-ui/scripts/musicgenres.js @@ -26,6 +26,13 @@ $(document).scrollTop(0); var html = ''; + var view = 'Thumb'; + + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Thumb') { + view = 'ThumbCard'; + } + } $('.listTopPaging', page).html(LibraryBrowser.getQueryPagingHtml({ startIndex: query.StartIndex, @@ -38,15 +45,30 @@ updateFilterControls(page); - html = LibraryBrowser.getPosterViewHtml({ - items: result.Items, - shape: "backdrop", - preferThumb: true, - context: 'music', - showItemCounts: true, - centerText: true, - lazy: true - }); + if (view == "Thumb") { + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "backdrop", + preferThumb: true, + context: 'music', + showItemCounts: true, + centerText: true, + lazy: true + }); + } + else if (view == "ThumbCard") { + + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "backdrop", + preferThumb: true, + context: 'music', + showItemCounts: true, + cardLayout: true, + lazy: true, + showTitle: true + }); + } $('#items', page).html(html).lazyChildren(); diff --git a/dashboard-ui/scripts/musicvideos.js b/dashboard-ui/scripts/musicvideos.js index f85e1749f1..5bc0fd34f6 100644 --- a/dashboard-ui/scripts/musicvideos.js +++ b/dashboard-ui/scripts/musicvideos.js @@ -37,13 +37,37 @@ updateFilterControls(page); - html = LibraryBrowser.getPosterViewHtml({ - items: result.Items, - shape: "square", - context: 'music', - showTitle: true, - centerText: true - }); + var view = 'Poster'; + + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Poster') { + view = 'PosterCard'; + } + } + + if (view == "Poster") { + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "square", + context: 'music', + showTitle: true, + lazy: true, + centerText: true + }); + } + else if (view == "PosterCard") { + + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "square", + context: 'music', + showTitle: true, + centerText: true, + cardLayout: true, + lazy: true, + showParentTitle: true + }); + } $('#items', page).html(html).trigger('create'); diff --git a/dashboard-ui/scripts/photos.js b/dashboard-ui/scripts/photos.js index aa9a7d68be..1f2062b615 100644 --- a/dashboard-ui/scripts/photos.js +++ b/dashboard-ui/scripts/photos.js @@ -1,6 +1,6 @@ (function ($, document) { - var view = LibraryBrowser.getDefaultItemsView('Poster', 'Poster'); + var view = LibraryBrowser.getDefaultItemsView('Poster', 'PosterCard'); // The base query options var query = { @@ -40,15 +40,36 @@ updateFilterControls(page); - // Poster - html = LibraryBrowser.getPosterViewHtml({ - items: result.Items, - shape: "auto", - context: getParameterByName('context') || 'photos', - showTitle: query.MediaTypes != 'Photo', - overlayText: true, - lazy: true - }); + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Poster') { + view = 'PosterCard'; + } + } + + if (view == "Poster") { + // Poster + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "auto", + context: getParameterByName('context') || 'photos', + showTitle: query.MediaTypes != 'Photo', + overlayText: true, + lazy: true + }); + } + else if (view == "PosterCard") { + + // Poster + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "auto", + context: getParameterByName('context') || 'photos', + showTitle: true, + lazy: true, + cardLayout: true, + showPremiereDate: true + }); + } var elem = $('#items', page).html(html).lazyChildren(); diff --git a/dashboard-ui/scripts/selectserver.js b/dashboard-ui/scripts/selectserver.js index 7715e46c62..71513d34b5 100644 --- a/dashboard-ui/scripts/selectserver.js +++ b/dashboard-ui/scripts/selectserver.js @@ -154,7 +154,7 @@ // Need the timeout because jquery mobile will not show a popup if there's currently already one in the process of closing setTimeout(function () { - Dashboard.hideLoadingMsg(); + Dashboard.hideModalLoadingMsg(); Dashboard.alert({ message: Globalize.translate('DefaultErrorMessage') }); @@ -164,12 +164,12 @@ function acceptInvitation(page, id) { - Dashboard.showLoadingMsg(); + Dashboard.showModalLoadingMsg(); // Add/Update connect info ConnectionManager.acceptServer(id).done(function () { - Dashboard.hideLoadingMsg(); + Dashboard.hideModalLoadingMsg(); loadPage(page); }).fail(function () { @@ -180,12 +180,12 @@ function deleteServer(page, id) { - Dashboard.showLoadingMsg(); + Dashboard.showModalLoadingMsg(); // Add/Update connect info ConnectionManager.deleteServer(id).done(function () { - Dashboard.hideLoadingMsg(); + Dashboard.hideModalLoadingMsg(); loadPage(page); }).fail(function () { @@ -197,12 +197,12 @@ function rejectInvitation(page, id) { - Dashboard.showLoadingMsg(); + Dashboard.showModalLoadingMsg(); // Add/Update connect info ConnectionManager.rejectServer(id).done(function () { - Dashboard.hideLoadingMsg(); + Dashboard.hideModalLoadingMsg(); loadPage(page); }).fail(function () { @@ -372,6 +372,8 @@ Dashboard.showLoadingMsg(); + Backdrops.setDefault(page); + ConnectionManager.getAvailableServers().done(function (servers) { servers = servers.slice(0); @@ -400,7 +402,17 @@ loadInvitations(page); } - $(document).on('pageshow', "#selectServerPage", function () { + $(document).on('pagebeforecreate', "#selectServerPage", function () { + + var page = this; + + if (ConnectionManager.isLoggedIntoConnect()) { + $(page).addClass('libraryPage').addClass(' noSecondaryNavPage').removeClass('standalonePage'); + } else { + $(page).removeClass('libraryPage').removeClass(' noSecondaryNavPage').addClass('standalonePage'); + } + + }).on('pagebeforeshow', "#selectServerPage", function () { var page = this; diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index b838998872..493559bed5 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -87,7 +87,7 @@ var Dashboard = { } Dashboard.hideLoadingMsg(); - if (!Dashboard.suppressAjaxErrors) { + if (!Dashboard.suppressAjaxErrors && data.type != 'GET') { setTimeout(function () { @@ -428,6 +428,10 @@ var Dashboard = { navigate: function (url, preserveQueryString) { + if (!url) { + throw new Error('url cannot be null or empty'); + } + var queryString = getWindowLocationSearch(); if (preserveQueryString && queryString) { url += queryString; @@ -1363,10 +1367,10 @@ var Dashboard = { if (AppInfo.hasLowImageBandwidth) { - quality -= 10; + quality -= 20; if (isBackdrop) { - quality -= 10; + quality -= 20; } } @@ -1421,6 +1425,8 @@ var Dashboard = { if (Dashboard.isRunningInCordova()) { + appName = "Emby Mobile"; + deviceName = store.getItem('cordovaDeviceName'); deviceId = store.getItem('cordovaDeviceId'); } @@ -1501,6 +1507,7 @@ var AppInfo = {}; AppInfo.enableLatestChannelItems = true; AppInfo.enableStudioTabs = true; AppInfo.enablePeopleTabs = true; + AppInfo.enableHomeFavoritesTab = true; AppInfo.enableTvEpisodesTab = true; AppInfo.enableMusicArtistsTab = true; AppInfo.enableHomeLatestTab = true; @@ -1617,6 +1624,10 @@ var AppInfo = {}; $(document.body).addClass('peopleTabDisabled'); } + if (!AppInfo.enableHomeFavoritesTab) { + $(document.body).addClass('homeFavoritesTabDisabled'); + } + if (!AppInfo.enableTvEpisodesTab) { $(document.body).addClass('tvEpisodesTabDisabled'); } @@ -1780,6 +1791,7 @@ var AppInfo = {}; $(onReady); } + })(); Dashboard.jQueryMobileInit(); diff --git a/dashboard-ui/scripts/syncactivity.js b/dashboard-ui/scripts/syncactivity.js index 6d800a5103..77c9bf26ae 100644 --- a/dashboard-ui/scripts/syncactivity.js +++ b/dashboard-ui/scripts/syncactivity.js @@ -103,7 +103,7 @@ // cardScalable html += ""; - html += '
'; + html += '
'; var textLines = []; diff --git a/dashboard-ui/scripts/tvgenres.js b/dashboard-ui/scripts/tvgenres.js index 0243143930..4a7992843e 100644 --- a/dashboard-ui/scripts/tvgenres.js +++ b/dashboard-ui/scripts/tvgenres.js @@ -1,6 +1,6 @@ (function ($, document) { - var view = LibraryBrowser.getDefaultItemsView('Thumb', 'Thumb'); + var view = LibraryBrowser.getDefaultItemsView('Thumb', 'ThumbCard'); // The base query options var query = { @@ -39,6 +39,15 @@ updateFilterControls(page); + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Thumb') { + view = 'ThumbCard'; + } + else if (view == 'Poster') { + view = 'PosterCard'; + } + } + if (view == "Thumb") { html = LibraryBrowser.getPosterViewHtml({ items: result.Items, @@ -63,6 +72,17 @@ lazy: true }); } + else if (view == "PosterCard") { + html = LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "portrait", + context: 'tv', + showItemCounts: true, + lazy: true, + cardLayout: true, + showTitle: true + }); + } else if (view == "Poster") { html = LibraryBrowser.getPosterViewHtml({ items: result.Items, diff --git a/dashboard-ui/scripts/tvlatest.js b/dashboard-ui/scripts/tvlatest.js index bff0b2151d..9ff7b4a85d 100644 --- a/dashboard-ui/scripts/tvlatest.js +++ b/dashboard-ui/scripts/tvlatest.js @@ -1,5 +1,14 @@ (function ($, document) { + function getView() { + + if (AppInfo.hasLowImageBandwidth) { + return 'ThumbCard'; + } + + return 'Thumb'; + } + $(document).on('pagebeforeshow', "#tvNextUpPage", function () { var userId = Dashboard.getCurrentUserId(); @@ -8,9 +17,11 @@ var page = this; - var limit = AppInfo.hasLowImageBandwidth ? - 20 : - 30; + var limit = 30; + + if (AppInfo.hasLowImageBandwidth) { + limit = 16; + } var options = { @@ -24,18 +35,43 @@ ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)).done(function (items) { - $('#latestEpisodes', page).html(LibraryBrowser.getPosterViewHtml({ - items: items, - shape: "backdrop", - preferThumb: true, - inheritThumb: false, - showParentTitle: false, - showUnplayedIndicator: false, - showChildCountIndicator: true, - overlayText: true, - lazy: true + var view = getView(); + var html = ''; - })).lazyChildren(); + if (view == 'ThumbCard') { + + html += LibraryBrowser.getPosterViewHtml({ + items: items, + shape: "backdrop", + preferThumb: true, + inheritThumb: false, + showUnplayedIndicator: false, + showChildCountIndicator: true, + overlayText: false, + showParentTitle: true, + lazy: true, + showTitle: true, + cardLayout: true + }); + + } else if (view == 'Thumb') { + + html += LibraryBrowser.getPosterViewHtml({ + items: items, + shape: "backdrop", + preferThumb: true, + inheritThumb: false, + showParentTitle: false, + showUnplayedIndicator: false, + showChildCountIndicator: true, + overlayText: false, + centerText: true, + lazy: true, + showTitle: false + }); + } + + $('#latestEpisodes', page).html(html).lazyChildren(); }); }); diff --git a/dashboard-ui/scripts/tvrecommended.js b/dashboard-ui/scripts/tvrecommended.js index 2015a1f654..3ac9576690 100644 --- a/dashboard-ui/scripts/tvrecommended.js +++ b/dashboard-ui/scripts/tvrecommended.js @@ -1,5 +1,23 @@ (function ($, document) { + function getView() { + + if (AppInfo.hasLowImageBandwidth) { + return 'ThumbCard'; + } + + return 'Thumb'; + } + + function getResumeView() { + + if (AppInfo.hasLowImageBandwidth) { + return 'PosterCard'; + } + + return 'Poster'; + } + function reload(page) { var context = ''; @@ -50,17 +68,37 @@ $('.noNextUpItems', page).show(); } - $('#nextUpItems', page).html(LibraryBrowser.getPosterViewHtml({ - items: result.Items, - shape: "backdrop", - showTitle: true, - showParentTitle: true, - overlayText: false, - context: context, - lazy: true, - preferThumb: true + var view = getView(); + var html = ''; - })).lazyChildren(); + if (view == 'ThumbCard') { + + html += LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "backdrop", + showTitle: true, + preferThumb: true, + showParentTitle: true, + lazy: true, + cardLayout: true, + context: 'tv' + }); + + } else if (view == 'Thumb') { + + html += LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "backdrop", + showTitle: true, + showParentTitle: true, + overlayText: false, + context: context, + lazy: true, + preferThumb: true + }); + } + + $('#nextUpItems', page).html(html).lazyChildren(); }); } @@ -99,16 +137,35 @@ $('.nextUpHeader', page).addClass('firstListHeader'); } - $('#resumableItems', page).html(LibraryBrowser.getPosterViewHtml({ - items: result.Items, - shape: "backdrop", - showTitle: true, - showParentTitle: true, - overlayText: screenWidth >= 800 && !AppInfo.hasLowImageBandwidth, - lazy: true, - context: 'tv' + var view = getResumeView(); + var html = ''; - })).lazyChildren(); + if (view == 'PosterCard') { + + html += LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "backdrop", + showTitle: true, + showParentTitle: true, + lazy: true, + cardLayout: true, + context: 'tv' + }); + + } else if (view == 'Poster') { + + html += LibraryBrowser.getPosterViewHtml({ + items: result.Items, + shape: "backdrop", + showTitle: true, + showParentTitle: true, + overlayText: screenWidth >= 800 && !AppInfo.hasLowImageBandwidth, + lazy: true, + context: 'tv' + }); + } + + $('#resumableItems', page).html(html).lazyChildren(); }); } diff --git a/dashboard-ui/scripts/tvshows.js b/dashboard-ui/scripts/tvshows.js index c9101130ce..5e4a2ae66d 100644 --- a/dashboard-ui/scripts/tvshows.js +++ b/dashboard-ui/scripts/tvshows.js @@ -1,6 +1,6 @@ (function ($, document) { - var view = LibraryBrowser.getDefaultItemsView('Poster', 'Poster'); + var view = LibraryBrowser.getDefaultItemsView('Poster', 'PosterCard'); // The base query options var query = { @@ -43,6 +43,15 @@ updateFilterControls(page); + if (AppInfo.hasLowImageBandwidth) { + if (view == 'Thumb') { + view = 'ThumbCard'; + } + else if (view == 'Poster') { + view = 'PosterCard'; + } + } + if (view == "Thumb") { html = LibraryBrowser.getPosterViewHtml({ @@ -50,7 +59,8 @@ shape: "backdrop", preferThumb: true, context: 'tv', - lazy: true + lazy: true, + overlayText: true }); } @@ -104,9 +114,9 @@ items: result.Items, shape: "portrait", context: 'tv', - showTitle: false, centerText: true, - lazy: true + lazy: true, + overlayText: true }); } diff --git a/dashboard-ui/scripts/tvupcoming.js b/dashboard-ui/scripts/tvupcoming.js index 5eb1ab03cd..6c72645f8d 100644 --- a/dashboard-ui/scripts/tvupcoming.js +++ b/dashboard-ui/scripts/tvupcoming.js @@ -5,7 +5,7 @@ var page = this; var limit = AppInfo.hasLowImageBandwidth ? - 20 : + 18 : 40; var query = { diff --git a/dashboard-ui/selectserver.html b/dashboard-ui/selectserver.html index 684de14615..710c2d7435 100644 --- a/dashboard-ui/selectserver.html +++ b/dashboard-ui/selectserver.html @@ -4,7 +4,7 @@ Emby -
+
diff --git a/dashboard-ui/thirdparty/apiclient/apiclient.js b/dashboard-ui/thirdparty/apiclient/apiclient.js index fb4ab61b1a..0a76189ebe 100644 --- a/dashboard-ui/thirdparty/apiclient/apiclient.js +++ b/dashboard-ui/thirdparty/apiclient/apiclient.js @@ -126,6 +126,7 @@ Events.trigger(self, 'requestfail', [ { url: this.url, + type: this.type, status: e.status, errorCode: e.getResponseHeader("X-Application-Error-Code") }]); diff --git a/dashboard-ui/thirdparty/apiclient/connectionmanager.js b/dashboard-ui/thirdparty/apiclient/connectionmanager.js index 3064437f6b..0bf246fff2 100644 --- a/dashboard-ui/thirdparty/apiclient/connectionmanager.js +++ b/dashboard-ui/thirdparty/apiclient/connectionmanager.js @@ -1070,39 +1070,56 @@ self.deleteServer = function (serverId) { - var connectToken = self.connectToken(); + var credentials = credentialProvider.credentials(); - if (!serverId) { - throw new Error("null serverId"); - } - if (!connectToken) { - throw new Error("null connectToken"); - } - if (!self.connectUserId()) { - throw new Error("null connectUserId"); - } + var serverInfo = credentials.servers = credentials.servers.filter(function (s) { + return s.ConnectServerId == serverId; + }); - var url = "https://connect.mediabrowser.tv/service/serverAuthorizations?serverId=" + serverId + "&userId=" + self.connectUserId(); - - return AjaxApi.ajax({ - type: "DELETE", - url: url, - headers: { - "X-Connect-UserToken": connectToken, - "X-Application": appName + "/" + appVersion - } - - }).done(function () { - - var credentials = credentialProvider.credentials(); + function onDone() { + + credentials = credentialProvider.credentials(); credentials.servers = credentials.servers.filter(function (s) { return s.ConnectServerId != serverId; }); credentialProvider.credentials(credentials); + } - }); + if (serverInfo.ExchangeToken) { + + var connectToken = self.connectToken(); + + if (!serverId) { + throw new Error("null serverId"); + } + if (!connectToken) { + throw new Error("null connectToken"); + } + if (!self.connectUserId()) { + throw new Error("null connectUserId"); + } + + var url = "https://connect.mediabrowser.tv/service/serverAuthorizations?serverId=" + serverId + "&userId=" + self.connectUserId(); + + return AjaxApi.ajax({ + type: "DELETE", + url: url, + headers: { + "X-Connect-UserToken": connectToken, + "X-Application": appName + "/" + appVersion + } + + }).done(onDone); + + } else { + + onDone(); + var deferred = DeferredBuilder.Deferred(); + deferred.resolve(); + return deferred.promise(); + } }; self.rejectServer = function (serverId) { diff --git a/dashboard-ui/thirdparty/cordova/remotecontrols.js b/dashboard-ui/thirdparty/cordova/remotecontrols.js index 15a9257455..acff4cd915 100644 --- a/dashboard-ui/thirdparty/cordova/remotecontrols.js +++ b/dashboard-ui/thirdparty/cordova/remotecontrols.js @@ -57,18 +57,15 @@ } var params = [artist, title, album, url, duration, elapsedTime]; - window.remoteControls.updateMetas(onUpdateMetasSuccess, onUpdateMetasFail, params); + try { + window.remoteControls.updateMetas(onUpdateMetasSuccess, onUpdateMetasFail, params); + } catch (err) { + onUpdateMetasFail(err); + } } function onStateChanged(e, state) { - //console.log('nowplaying event: ' + e.type); - var player = this; - - if (player.isDefaultPlayer && state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') { - return; - } - updatePlayerState(state); } @@ -115,7 +112,12 @@ var elapsedTime = 0; var params = [artist, title, album, image, duration, elapsedTime]; - window.remoteControls.updateMetas(onUpdateMetasSuccess, onUpdateMetasFail, params); + + try { + window.remoteControls.updateMetas(onUpdateMetasSuccess, onUpdateMetasFail, params); + } catch (err) { + onUpdateMetasFail(err); + } } function onUpdateMetasSuccess() { @@ -125,7 +127,7 @@ function onUpdateMetasFail(fail) { - console.log('onUpdateMetasFail' + fail); + console.log('onUpdateMetasFail: ' + fail); } function bindToPlayer(player) { @@ -138,6 +140,8 @@ return; } + console.log('binding remotecontrols to MediaPlayer'); + player.getPlayerState().done(function (state) { if (state.NowPlayingItem) { @@ -153,8 +157,12 @@ .on('positionchange.cordovaremote', onStateChanged); } + console.log('binding remotecontrols to MediaController'); + document.addEventListener("deviceready", function () { + console.log('binding remotecontrols to MediaController'); + $(function () { $(MediaController).on('playerchange', function () { diff --git a/dashboard-ui/thirdparty/cordova/serverdiscovery.js b/dashboard-ui/thirdparty/cordova/serverdiscovery.js index 2c7dba0511..d5aa72f9f7 100644 --- a/dashboard-ui/thirdparty/cordova/serverdiscovery.js +++ b/dashboard-ui/thirdparty/cordova/serverdiscovery.js @@ -14,28 +14,29 @@ return String.fromCharCode.apply(null, new Uint16Array(buf)); } - globalScope.ServerDiscovery = { + function findServersInternal(timeoutMs) { - findServers: function (timeoutMs) { + var deferred = DeferredBuilder.Deferred(); - var deferred = DeferredBuilder.Deferred(); + var servers = []; - var servers = []; + // Expected server properties + // Name, Id, Address, EndpointAddress (optional) - // Expected server properties - // Name, Id, Address, EndpointAddress (optional) + var chrome = globalScope.chrome; - var chrome = globalScope.chrome; + if (!chrome) { + deferred.resolveWith(null, [servers]); + return deferred.promise(); + } - if (!chrome) { - deferred.resolveWith(null, [servers]); - return deferred.promise(); - } + var isTimedOut = false; + var timeout; + var socketId; - var isTimedOut = false; - var socketId; + function startTimer() { - var timeout = setTimeout(function () { + timeout = setTimeout(function () { isTimedOut = true; deferred.resolveWith(null, [servers]); @@ -43,22 +44,22 @@ if (socketId) { chrome.sockets.udp.onReceive.removeListener(onReceive); chrome.sockets.udp.close(socketId); - - } }, timeoutMs); + } - function onReceive(info) { + function onReceive(info) { - console.log('ServerDiscovery message received'); + console.log('ServerDiscovery message received'); - console.log(info); + console.log(info); - if (info.socketId == socketId) { + if (info.socketId == socketId) { + try { var json = arrayBufferToString(info.data); - + console.log('Server discovery json: ' + json); var server = JSON.parse(json); server.RemoteAddress = info.remoteAddress; @@ -68,37 +69,61 @@ } servers.push(server); + } catch (err) { + console.log('Error receiving server info: ' + err); } } + } - var port = 7359; - chrome.sockets.udp.create(function (createInfo) { + var port = 7359; + console.log('chrome.sockets.udp.create'); + chrome.sockets.udp.create(function (createInfo) { - socketId = createInfo.socketId; + socketId = createInfo.socketId; - chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', port, function (result) { + console.log('chrome.sockets.udp.bind'); - var data = stringToArrayBuffer('who is EmbyServer?'); + chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', port, function (result) { - chrome.sockets.udp.send(createInfo.socketId, data, '255.255.255.255', port, function (result) { - if (result < 0) { - console.log('send fail: ' + result); - chrome.sockets.udp.close(createInfo.socketId); + var data = stringToArrayBuffer('who is EmbyServer?'); - if (!isTimedOut) { - clearTimeout(timeout); - deferred.resolveWith(null, [servers]); - } + console.log('chrome.sockets.udp.send'); + chrome.sockets.udp.send(createInfo.socketId, data, '255.255.255.255', port, function (result) { - } else { + if (result < 0) { + console.log('send fail: ' + result); + deferred.resolveWith(null, [servers]); + chrome.sockets.udp.close(createInfo.socketId); - console.log('sendTo: success ' + port); + } else { - if (!isTimedOut) { - chrome.sockets.udp.onReceive.addListener(onReceive); - } - } - }); + console.log('sendTo: success ' + port); + + startTimer(); + chrome.sockets.udp.onReceive.addListener(onReceive); + } + }); + }); + }); + + return deferred.promise(); + } + + globalScope.ServerDiscovery = { + + findServers: function (timeoutMs) { + + var deferred = DeferredBuilder.Deferred(); + + deviceReadyPromise.done(function () { + + findServersInternal(timeoutMs).done(function (result) { + + deferred.resolveWith(null, [result]); + + }).fail(function () { + + deferred.reject(); }); }); @@ -106,4 +131,14 @@ } }; + var deviceReadyDeferred = DeferredBuilder.Deferred(); + var deviceReadyPromise = deviceReadyDeferred.promise(); + + document.addEventListener("deviceready", function () { + + deviceReadyDeferred.resolve(); + + }, false); + + })(window); \ No newline at end of file diff --git a/dashboard-ui/thirdparty/jquery.unveil-custom.js b/dashboard-ui/thirdparty/jquery.unveil-custom.js index 69373172a0..20c293add5 100644 --- a/dashboard-ui/thirdparty/jquery.unveil-custom.js +++ b/dashboard-ui/thirdparty/jquery.unveil-custom.js @@ -12,13 +12,23 @@ var unveilId = 0; - // Test search before setting to 0 - var threshold = 100; + + function getThreshold() { + + var threshold = 100; + + if (window.AppInfo && AppInfo.hasLowImageBandwidth) { + return 0; + } + + // Test search before setting to 0 + return 100; + } $.fn.unveil = function () { var $w = $(window), - th = threshold || 0, + th = getThreshold(), attrib = "data-src", images = this, loaded; @@ -90,7 +100,7 @@ var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB, dbVersion = 1.0; - var dbName = "emby3"; + var dbName = "emby4"; var imagesStoreName = "images"; function createObjectStore(dataBase) { @@ -160,9 +170,10 @@ var self = this; - var openPromise = openDb().done(function (db) { + openDb().done(function (db) { self._db = db; + window.ImageStore = self; }); self.addImageToDatabase = function (blob, key) { @@ -176,13 +187,6 @@ var put = transaction.objectStore(imagesStoreName).put(blob, key); }; - self.revokeUrl = function (url) { - - // Get window.URL object - var URL = window.URL || window.webkitURL; - URL.revokeObjectURL(url); - }; - self.db = function () { return self._db; @@ -283,6 +287,7 @@ self.addImageToDatabase(dataURL, key); deferred.resolve(); } catch (err) { + console.log("Error adding image to database"); deferred.reject(); } } else { @@ -301,13 +306,9 @@ setImageIntoElement(elem, url); } - openPromise.done(function () { + self.getImageUrl(url).done(function (localUrl) { - self.getImageUrl(url).done(function (localUrl) { - - setImageIntoElement(elem, localUrl); - - }).fail(onFail); + setImageIntoElement(elem, localUrl); }).fail(onFail); @@ -318,9 +319,10 @@ var self = this; - var openPromise = openDb().done(function (db) { + openDb().done(function (db) { self._db = db; + window.ImageStore = self; }); self.addImageToDatabase = function (blob, key) { @@ -334,13 +336,6 @@ var put = transaction.objectStore(imagesStoreName).put(blob, key); }; - self.revokeUrl = function (url) { - - // Get window.URL object - var URL = window.URL || window.webkitURL; - URL.revokeObjectURL(url); - }; - self.db = function () { return self._db; @@ -437,6 +432,8 @@ self.addImageToDatabase(blob, key); deferred.resolve(); } catch (err) { + console.log("Error adding blob to database"); + alert("Error adding blob to database"); deferred.reject(); } } else { @@ -455,16 +452,250 @@ setImageIntoElement(elem, url); } - openPromise.done(function () { + self.getImageUrl(url).done(function (localUrl) { - self.getImageUrl(url).done(function (localUrl) { - - setImageIntoElement(elem, localUrl); - - }).fail(onFail); + setImageIntoElement(elem, localUrl); }).fail(onFail); + }; + } + function indexedDbWebpImageStore() { + + var self = this; + + openDb().done(function (db) { + + self._db = db; + window.ImageStore = self; + }); + + self.addImageToDatabase = function (blob, key) { + + console.log("addImageToDatabase"); + + // Open a transaction to the database + var transaction = self.db().transaction([imagesStoreName], "readwrite"); + + // Put the blob into the dabase + var put = transaction.objectStore(imagesStoreName).put(blob, key); + }; + + self.db = function () { + + return self._db; + }; + + self.get = function (key) { + + var deferred = DeferredBuilder.Deferred(); + + var transaction = self.db().transaction([imagesStoreName], "readonly"); + + // Open a transaction to the database + var getRequest = transaction.objectStore(imagesStoreName).get(key); + + getRequest.onsuccess = function (event) { + + var imgFile = event.target.result; + + if (imgFile) { + deferred.resolveWith(null, [imgFile]); + } else { + deferred.reject(); + } + }; + + getRequest.onerror = function () { + deferred.reject(); + }; + + return deferred.promise(); + }; + + self.getImageUrl = function (originalUrl) { + + console.log('getImageUrl:' + originalUrl); + + var key = CryptoJS.SHA1(originalUrl).toString(); + + var deferred = DeferredBuilder.Deferred(); + + self.get(key).done(function (url) { + + deferred.resolveWith(null, [url]); + + }).fail(function () { + + self.downloadImage(originalUrl, key).done(function () { + self.get(key).done(function (url) { + + deferred.resolveWith(null, [url]); + + }).fail(function () { + + deferred.reject(); + }); + }).fail(function () { + + deferred.reject(); + }); + }); + + return deferred.promise(); + }; + + self.downloadImage = function (url, key) { + + var deferred = DeferredBuilder.Deferred(); + + console.log('downloadImage:' + url); + + // Create XHR + var xhr = new XMLHttpRequest(); + + xhr.open("GET", url, true); + // Set the responseType to blob + xhr.responseType = "arraybuffer"; + + xhr.addEventListener("load", function () { + + if (xhr.status === 200) { + console.log("Image retrieved"); + + try { + + + self.addImageToDatabase(this.response, key); + deferred.resolve(); + } catch (err) { + console.log("Error adding image to database"); + deferred.reject(); + } + } else { + deferred.reject(); + } + }, false); + + // Send XHR + xhr.send(); + return deferred.promise(); + }; + + function decode(data, elem) { + + console.log('decoding webp'); + + var WebPImage = { width: { value: 0 }, height: { value: 0 } } + var decoder = new WebPDecoder(); + + //Config, you can set all arguments or what you need, nothing no objeect + var config = decoder.WebPDecoderConfig; + var output_buffer = config.j; + var bitstream = config.input; + + if (!decoder.WebPInitDecoderConfig(config)) { + throw new Error("Library version mismatch!\n"); + } + + var StatusCode = decoder.VP8StatusCode; + + var status = decoder.WebPGetFeatures(data, data.length, bitstream); + if (status != 0) { + console.log('error'); + } + + var mode = decoder.WEBP_CSP_MODE; + output_buffer.J = 4; + + status = decoder.WebPDecode(data, data.length, config); + + var ok = (status == 0); + if (!ok) { + throw new Error("Decoding of %s failed.\n"); + } + + drawIntoElement(output_buffer, elem); + } + + function drawIntoElement(output_buffer, elem) { + + console.log('drawing canvas'); + + var bitmap = output_buffer.c.RGBA.ma; + + var canvas = document.createElement("canvas"); + + var biHeight = output_buffer.height; var biWidth = output_buffer.width; + + canvas.height = biHeight; + canvas.width = biWidth; + + var context = canvas.getContext('2d'); + var output = context.createImageData(canvas.width, canvas.height); + var outputData = output.data; + + for (var h = 0; h < biHeight; h++) { + for (var w = 0; w < biWidth; w++) { + outputData[0 + w * 4 + (biWidth * 4) * h] = bitmap[1 + w * 4 + (biWidth * 4) * h]; + outputData[1 + w * 4 + (biWidth * 4) * h] = bitmap[2 + w * 4 + (biWidth * 4) * h]; + outputData[2 + w * 4 + (biWidth * 4) * h] = bitmap[3 + w * 4 + (biWidth * 4) * h]; + outputData[3 + w * 4 + (biWidth * 4) * h] = bitmap[0 + w * 4 + (biWidth * 4) * h]; + + }; + } + + context.putImageData(output, 0, 0); + + elem.appendChild(canvas); + } + + self.setImageInto = function (elem, url) { + + if (url.indexOf('format=webp') == -1 || elem.tagName != 'DIV') { + + setImageIntoElement(elem, url); + return; + } + + // Create XHR + var xhr = new XMLHttpRequest(); + + xhr.open("GET", url, true); + // Set the responseType to blob + xhr.responseType = "arraybuffer"; + + xhr.addEventListener("load", function () { + + if (xhr.status === 200) { + console.log("Image retrieved"); + + try { + + var arr = new Uint8Array(this.response); + + //// Convert the int array to a binary string + //// We have to use apply() as we are converting an *array* + //// and String.fromCharCode() takes one or more single values, not + //// an array. + //var raw = String.fromCharCode.apply(null, arr); + + //// This works!!! + //var b64 = btoa(raw); + //var dataURL = "data:image/jpeg;base64," + b64; + + console.log(url); + decode(arr, elem); + + } catch (err) { + console.log("Error adding image to database"); + } + } else { + } + }, false); + + // Send XHR + xhr.send(); }; } @@ -475,17 +706,16 @@ self.setImageInto = setImageIntoElement; } - if ($.browser.safari && indexedDB && window.Blob) { - console.log('creating indexedDbBlobImageStore'); - window.ImageStore = new indexedDbBlobImageStore(); - } - else if ($.browser.safari && indexedDB) { - console.log('creating indexedDbImageStore'); - window.ImageStore = new indexedDbImageStore(); - } - else { - console.log('creating simpleImageStore'); - window.ImageStore = new simpleImageStore(); - } + console.log('creating simpleImageStore'); + window.ImageStore = new simpleImageStore(); + + //if ($.browser.safari && indexedDB && window.Blob) { + // console.log('creating indexedDbBlobImageStore'); + // new indexedDbBlobImageStore(); + //} + //else if ($.browser.safari && indexedDB) { + // console.log('creating indexedDbImageStore'); + // new indexedDbImageStore(); + //} })(); \ No newline at end of file diff --git a/dashboard-ui/tvrecommended.html b/dashboard-ui/tvrecommended.html index 756913afdb..e192c1d7a0 100644 --- a/dashboard-ui/tvrecommended.html +++ b/dashboard-ui/tvrecommended.html @@ -10,7 +10,7 @@ ${TabHome} ${TabLatest} ${TabNextUp} - ${TabFavorites} + ${TabFavorites} ${TabUpcoming}