diff --git a/dashboard-ui/apiclient/ajax.js b/dashboard-ui/apiclient/ajax.js index 4b85f5885a..c0c191ad04 100644 --- a/dashboard-ui/apiclient/ajax.js +++ b/dashboard-ui/apiclient/ajax.js @@ -1,12 +1,12 @@ (function (globalScope) { - globalScope.AjaxApi = { + globalScope.HttpClient = { param: function (params) { return jQuery.param(params); }, - ajax: function (request) { + send: function (request) { request.timeout = request.timeout || 30000; diff --git a/dashboard-ui/apiclient/alt/ajax.js b/dashboard-ui/apiclient/alt/ajax.js index 22613fbb7f..43f47bc5d5 100644 --- a/dashboard-ui/apiclient/alt/ajax.js +++ b/dashboard-ui/apiclient/alt/ajax.js @@ -1,12 +1,12 @@ (function (globalScope, angular) { - globalScope.AjaxApi = { + globalScope.HttpClient = { param: function(params) { return serialize(params); }, - ajax: function(options) { + send: function(options) { var request = getAngularRequest(options), defer = globalScope.DeferredBuilder.Deferred(); @@ -91,7 +91,7 @@ for (var key in jParams) { if (!paramMap[key]) { // This parameter hasn't been implemented in the paramMap object - Logger.log('ERROR: ajax option property "' + key + '" not implemented by AjaxApi.'); + Logger.log('ERROR: ajax option property "' + key + '" not implemented by HttpClient.'); continue; } diff --git a/dashboard-ui/apiclient/apiclient.js b/dashboard-ui/apiclient/apiclient.js index ab16a21182..09a2d5a0e0 100644 --- a/dashboard-ui/apiclient/apiclient.js +++ b/dashboard-ui/apiclient/apiclient.js @@ -115,7 +115,7 @@ name = name.split('&').join('-'); name = name.split('?').join('-'); - var val = AjaxApi.param({ name: name }); + var val = HttpClient.param({ name: name }); return val.substring(val.indexOf('=') + 1).replace("'", '%27'); }; @@ -175,7 +175,7 @@ if (self.enableAutomaticNetworking === false || request.type != "GET") { logger.log('Requesting url without automatic networking: ' + request.url); - return AjaxApi.ajax(request).fail(onRequestFail); + return HttpClient.send(request).fail(onRequestFail); } var deferred = DeferredBuilder.Deferred(); @@ -218,7 +218,7 @@ var timeout = connectionMode == MediaBrowser.ConnectionMode.Local ? 5000 : 15000; - AjaxApi.ajax({ + HttpClient.send({ type: "GET", url: url + "/system/info/public", @@ -282,7 +282,7 @@ request.timeout = 15000; - AjaxApi.ajax(request).done(function (response) { + HttpClient.send(request).done(function (response) { deferred.resolve(response, 0); @@ -356,7 +356,7 @@ url += name; if (params) { - url += "?" + AjaxApi.param(params); + url += "?" + HttpClient.param(params); } return url; diff --git a/dashboard-ui/apiclient/connectionmanager.js b/dashboard-ui/apiclient/connectionmanager.js index 6dc7235d44..376eb1597e 100644 --- a/dashboard-ui/apiclient/connectionmanager.js +++ b/dashboard-ui/apiclient/connectionmanager.js @@ -85,7 +85,7 @@ logger.log('tryConnect url: ' + url); - return AjaxApi.ajax({ + return HttpClient.send({ type: "GET", url: url, @@ -378,7 +378,7 @@ var url = "https://connect.mediabrowser.tv/service/user?id=" + userId; - return AjaxApi.ajax({ + return HttpClient.send({ type: "GET", url: url, dataType: "json", @@ -403,7 +403,7 @@ url += "/Connect/Exchange?format=json&ConnectUserId=" + credentials.ConnectUserId; - return AjaxApi.ajax({ + return HttpClient.send({ type: "GET", url: url, dataType: "json", @@ -429,7 +429,7 @@ var url = MediaBrowser.ServerInfo.getServerAddress(server, connectionMode); - AjaxApi.ajax({ + HttpClient.send({ type: "GET", url: url + "/system/info", @@ -444,7 +444,7 @@ if (server.UserId) { - AjaxApi.ajax({ + HttpClient.send({ type: "GET", url: url + "/users/" + server.UserId, @@ -634,7 +634,7 @@ var url = "https://connect.mediabrowser.tv/service/servers?userId=" + credentials.ConnectUserId; - AjaxApi.ajax({ + HttpClient.send({ type: "GET", url: url, dataType: "json", @@ -1083,7 +1083,7 @@ var md5 = self.getConnectPasswordHash(password); - AjaxApi.ajax({ + HttpClient.send({ type: "POST", url: "https://connect.mediabrowser.tv/service/user/authenticate", data: { @@ -1146,7 +1146,7 @@ var md5 = self.getConnectPasswordHash(password); - AjaxApi.ajax({ + HttpClient.send({ type: "POST", url: "https://connect.mediabrowser.tv/service/register", data: { @@ -1218,7 +1218,7 @@ var url = "https://connect.mediabrowser.tv/service/servers?userId=" + self.connectUserId() + "&status=Waiting"; - return AjaxApi.ajax({ + return HttpClient.send({ type: "GET", url: url, dataType: "json", @@ -1265,7 +1265,7 @@ var url = "https://connect.mediabrowser.tv/service/serverAuthorizations?serverId=" + serverId + "&userId=" + self.connectUserId(); - return AjaxApi.ajax({ + return HttpClient.send({ type: "DELETE", url: url, headers: { @@ -1300,7 +1300,7 @@ var url = "https://connect.mediabrowser.tv/service/serverAuthorizations?serverId=" + serverId + "&userId=" + self.connectUserId(); - return AjaxApi.ajax({ + return HttpClient.send({ type: "DELETE", url: url, headers: { @@ -1327,7 +1327,7 @@ var url = "https://connect.mediabrowser.tv/service/ServerAuthorizations/accept?serverId=" + serverId + "&userId=" + self.connectUserId(); - return AjaxApi.ajax({ + return HttpClient.send({ type: "GET", url: url, headers: { diff --git a/dashboard-ui/bower_components/iron-meta/.bower.json b/dashboard-ui/bower_components/iron-meta/.bower.json index 8119ebcf41..9e650790be 100644 --- a/dashboard-ui/bower_components/iron-meta/.bower.json +++ b/dashboard-ui/bower_components/iron-meta/.bower.json @@ -25,14 +25,14 @@ "web-component-tester": "*", "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" }, - "homepage": "https://github.com/polymerelements/iron-meta", + "homepage": "https://github.com/PolymerElements/iron-meta", "_release": "1.0.3", "_resolution": { "type": "version", "tag": "v1.0.3", "commit": "91529259262b0d8f33fed44bc3fd47aedf35cb04" }, - "_source": "git://github.com/polymerelements/iron-meta.git", + "_source": "git://github.com/PolymerElements/iron-meta.git", "_target": "^1.0.0", - "_originalSource": "polymerelements/iron-meta" + "_originalSource": "PolymerElements/iron-meta" } \ No newline at end of file diff --git a/dashboard-ui/bower_components/paper-styles/.bower.json b/dashboard-ui/bower_components/paper-styles/.bower.json index f16c89e87a..32205aaa01 100644 --- a/dashboard-ui/bower_components/paper-styles/.bower.json +++ b/dashboard-ui/bower_components/paper-styles/.bower.json @@ -34,7 +34,7 @@ "tag": "v1.0.7", "commit": "c65f5ce6b898bb756fca35cedaa53c3e8011abeb" }, - "_source": "git://github.com/polymerelements/paper-styles.git", + "_source": "git://github.com/PolymerElements/paper-styles.git", "_target": "^1.0.0", - "_originalSource": "polymerelements/paper-styles" + "_originalSource": "PolymerElements/paper-styles" } \ No newline at end of file diff --git a/dashboard-ui/cordova/android/androidcredentials.js b/dashboard-ui/cordova/android/androidcredentials.js index ff0cdba90f..21beec983b 100644 --- a/dashboard-ui/cordova/android/androidcredentials.js +++ b/dashboard-ui/cordova/android/androidcredentials.js @@ -37,8 +37,8 @@ return id.toString(); } function initAjax() { - baseAjaxMethod = AjaxApi.ajax; - AjaxApi.ajax = sendRequest; + baseAjaxMethod = HttpClient.send; + HttpClient.send = sendRequest; } function sendRequest(request) { diff --git a/dashboard-ui/css/site.css b/dashboard-ui/css/site.css index 5699d819f3..b88e17708d 100644 --- a/dashboard-ui/css/site.css +++ b/dashboard-ui/css/site.css @@ -1,28 +1,4 @@ -@font-face { - font-family: 'Material Icons'; - font-style: normal; - font-weight: 400; - src: url(../thirdparty/materialicons/MaterialIcons-Regular.eot); /* For IE6-8 */ - src: local('Material Icons'), local('MaterialIcons-Regular'), url(../thirdparty/materialicons/MaterialIcons-Regular.woff2) format('woff2'), url(../thirdparty/materialicons/MaterialIcons-Regular.woff) format('woff'), url(../thirdparty/materialicons/MaterialIcons-Regular.ttf) format('truetype'); -} - -.material-icons { - font-family: 'Material Icons'; - font-weight: normal; - font-style: normal; - display: inline-block; - text-transform: none; - /* Support for all WebKit browsers. */ - -webkit-font-smoothing: antialiased; - /* Support for Safari and Chrome. */ - text-rendering: optimizeLegibility; - /* Support for Firefox. */ - -moz-osx-font-smoothing: grayscale; - /* Support for IE. */ - font-feature-settings: 'liga'; -} - -/* cyrillic-ext */ +/* cyrillic-ext */ @font-face { font-family: 'Roboto'; font-style: normal; diff --git a/dashboard-ui/scripts/actionsheet.js b/dashboard-ui/scripts/actionsheet.js index 9d38494e4f..94a858daf8 100644 --- a/dashboard-ui/scripts/actionsheet.js +++ b/dashboard-ui/scripts/actionsheet.js @@ -66,11 +66,12 @@ return o.ironIcon; }).length; + html += ''; for (var i = 0, length = options.items.length; i < length; i++) { var option = options.items[i]; - html += ''; + html += ''; if (option.ironIcon) { html += ''; @@ -79,8 +80,9 @@ html += ''; } html += '' + option.name + ''; - html += ''; + html += ''; } + html += ''; if (isScrollable) { html += ''; @@ -106,7 +108,7 @@ $(this).remove(); }); - $('.btnOption', dlg).on('click', function () { + $('.actionSheetMenuItem', dlg).on('click', function () { var selectedId = this.getAttribute('data-id'); diff --git a/dashboard-ui/scripts/backdrops.js b/dashboard-ui/scripts/backdrops.js index 0fc2fc5232..9b835f0e0f 100644 --- a/dashboard-ui/scripts/backdrops.js +++ b/dashboard-ui/scripts/backdrops.js @@ -122,10 +122,6 @@ return false; } - if ($.browser.android && AppInfo.isNativeApp) { - return screen.availWidth >= 1200; - } - if ($.browser.mobile) { return false; } diff --git a/dashboard-ui/scripts/favorites.js b/dashboard-ui/scripts/favorites.js index aa3d0e10e8..8e73c8aad8 100644 --- a/dashboard-ui/scripts/favorites.js +++ b/dashboard-ui/scripts/favorites.js @@ -108,6 +108,8 @@ $.when(promises).done(function () { Dashboard.hideLoadingMsg(); + + LibraryBrowser.setLastRefreshed(page); }); } @@ -117,7 +119,9 @@ var userId = Dashboard.getCurrentUserId(); - loadSections(page, userId); + if (LibraryBrowser.needsRefresh(page)) { + loadSections(page, userId); + } }); })(jQuery, document); \ No newline at end of file diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index 3097522ea4..3402e0c682 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -3,7 +3,7 @@ var pageSizeKey = 'pagesize_v4'; return { - getDefaultPageSize: function(key, defaultValue) { + getDefaultPageSize: function (key, defaultValue) { var saved = appStorage.getItem(key || pageSizeKey); @@ -21,13 +21,13 @@ return isChrome ? 200 : 100; }, - getDefaultItemsView: function(view, mobileView) { + getDefaultItemsView: function (view, mobileView) { return $.browser.mobile ? mobileView : view; }, - loadSavedQueryValues: function(key, query) { + loadSavedQueryValues: function (key, query) { var values = appStorage.getItem(key + '_' + Dashboard.getCurrentUserId()); @@ -41,7 +41,7 @@ return query; }, - saveQueryValues: function(key, query) { + saveQueryValues: function (key, query) { var values = {}; @@ -59,7 +59,7 @@ } }, - saveViewSetting: function(key, value) { + saveViewSetting: function (key, value) { try { appStorage.setItem(key + '_' + Dashboard.getCurrentUserId() + '_view', value); @@ -68,7 +68,7 @@ } }, - getSavedViewSetting: function(key) { + getSavedViewSetting: function (key) { var deferred = $.Deferred(); var val = appStorage.getItem(key + '_' + Dashboard.getCurrentUserId() + '_view'); @@ -77,25 +77,39 @@ return deferred.promise(); }, - needsRefresh: function(elem) { + needsRefresh: function (elem) { - var last = elem.getAttribute('data-lastrefresh') || '0'; + var last = parseInt(elem.getAttribute('data-lastrefresh') || '0'); + + if (!last) { + return true; + } if (NavHelper.isBack()) { return false; } var now = new Date().getTime(); - if ((now - parseInt(last)) < 90000) { + var cacheDuration = 300000; + if (!AppInfo.isNativeApp && ($.browser.ipad || $.browser.iphone || $.browser.android)) { + cacheDuration = 10000; + } + + else if (!$.browser.mobile) { + cacheDuration = 60000; + } + + if ((now - last) < cacheDuration) { return false; } return true; }, - setLastRefreshed: function(elem) { - + setLastRefreshed: function (elem) { + elem.setAttribute('data-lastrefresh', new Date().getTime()); + elem.classList.add('hasrefreshtime'); }, getDateParamValue: function (date) { @@ -535,13 +549,6 @@ var href = LibraryBrowser.getHrefInternal(item, context); - if (context) { - if (context != 'livetv') { - href += href.indexOf('?') == -1 ? "?context=" : "&context="; - href += context; - } - } - if (context != 'livetv') { if (topParentId == null && context != 'playlists') { topParentId = LibraryMenu.getTopParentId(); @@ -566,6 +573,8 @@ return item.url; } + var contextSuffix = context ? ('&context=' + context) : ''; + // Handle search hints var id = item.Id || item.ItemId; @@ -632,48 +641,48 @@ return "livetvprogram.html?id=" + id; } if (item.Type == "Series") { - return "itemdetails.html?id=" + id; + return "itemdetails.html?id=" + id + contextSuffix; } if (item.Type == "Season") { - return "itemdetails.html?id=" + id; + return "itemdetails.html?id=" + id + contextSuffix; } if (item.Type == "BoxSet") { - return "itemdetails.html?id=" + id; + return "itemdetails.html?id=" + id + contextSuffix; } if (item.Type == "MusicAlbum") { - return "itemdetails.html?id=" + id; + return "itemdetails.html?id=" + id + contextSuffix; } if (item.Type == "GameSystem") { - return "itemdetails.html?id=" + id; + return "itemdetails.html?id=" + id + contextSuffix; } if (item.Type == "Genre") { - return "itembynamedetails.html?id=" + id; + return "itembynamedetails.html?id=" + id + contextSuffix; } if (item.Type == "MusicGenre") { - return "itembynamedetails.html?id=" + id; + return "itembynamedetails.html?id=" + id + contextSuffix; } if (item.Type == "GameGenre") { - return "itembynamedetails.html?id=" + id; + return "itembynamedetails.html?id=" + id + contextSuffix; } if (item.Type == "Studio") { - return "itembynamedetails.html?id=" + id; + return "itembynamedetails.html?id=" + id + contextSuffix; } if (item.Type == "Person") { - return "itembynamedetails.html?id=" + id; + return "itembynamedetails.html?id=" + id + contextSuffix; } if (item.Type == "Recording") { - return "livetvrecording.html?id=" + id; + return "livetvrecording.html?id=" + id + contextSuffix; } if (item.Type == "MusicArtist") { - return "itembynamedetails.html?id=" + id; + return "itembynamedetails.html?id=" + id + contextSuffix; } if (item.IsFolder) { return id ? "itemlist.html?parentId=" + id : "#"; } - return "itemdetails.html?id=" + id; + return "itemdetails.html?id=" + id + contextSuffix; }, getImageUrl: function (item, type, index, options) { diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index 739878d954..ad9937c23a 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -115,7 +115,7 @@ var resumePosition = (item.UserData || {}).PlaybackPositionTicks || 0; - html += ''; + html += ''; buttonCount++; } @@ -1228,6 +1228,10 @@ $(apiClient).off('websocketmessage', onWebSocketMessage).on('websocketmessage', onWebSocketMessage); } + function clearRefreshTimes() { + $('.hasrefreshtime').removeClass('hasrefreshtime').removeAttr('data-lastrefresh'); + } + Dashboard.ready(function () { if (window.ApiClient) { @@ -1237,6 +1241,9 @@ $(ConnectionManager).on('apiclientcreated', function (e, apiClient) { initializeApiClient(apiClient); }); + + Events.on(ConnectionManager, 'localusersignedin', clearRefreshTimes); + Events.on(ConnectionManager, 'localusersignedout', clearRefreshTimes); }); })(jQuery, document, window); \ No newline at end of file diff --git a/dashboard-ui/scripts/livetvchannels.js b/dashboard-ui/scripts/livetvchannels.js index d4814ca626..855d41474f 100644 --- a/dashboard-ui/scripts/livetvchannels.js +++ b/dashboard-ui/scripts/livetvchannels.js @@ -121,6 +121,7 @@ if (LibraryBrowser.needsRefresh(page)) { query.UserId = Dashboard.getCurrentUserId(); LibraryBrowser.loadSavedQueryValues('movies', query); + query.Limit = query.Limit || LibraryBrowser.getDefaultPageSize(); reloadItems(page); updateFilterControls(this); } diff --git a/dashboard-ui/scripts/livetvrecordings.js b/dashboard-ui/scripts/livetvrecordings.js index 16f9b62983..600738d24a 100644 --- a/dashboard-ui/scripts/livetvrecordings.js +++ b/dashboard-ui/scripts/livetvrecordings.js @@ -89,6 +89,7 @@ renderRecordings($('#latestRecordings', page), result.Items); + LibraryBrowser.setLastRefreshed(page); }); ApiClient.getLiveTvRecordingGroups({ @@ -106,7 +107,9 @@ var page = this; - reload(page); + if (LibraryBrowser.needsRefresh(page)) { + reload(page); + } }); diff --git a/dashboard-ui/scripts/livetvseriestimers.js b/dashboard-ui/scripts/livetvseriestimers.js index 4992375b36..e5516dd5d4 100644 --- a/dashboard-ui/scripts/livetvseriestimers.js +++ b/dashboard-ui/scripts/livetvseriestimers.js @@ -97,6 +97,7 @@ renderTimers(page, result.Items); + LibraryBrowser.setLastRefreshed(page); }); } @@ -120,7 +121,9 @@ var page = this; - reload(page); + if (LibraryBrowser.needsRefresh(page)) { + reload(page); + } }).on('pageinit', "#liveTvSeriesTimersPage", function () { diff --git a/dashboard-ui/scripts/livetvtimers.js b/dashboard-ui/scripts/livetvtimers.js index 4a93c45bfd..c0691a78f2 100644 --- a/dashboard-ui/scripts/livetvtimers.js +++ b/dashboard-ui/scripts/livetvtimers.js @@ -104,6 +104,7 @@ renderTimers(page, result.Items); + LibraryBrowser.setLastRefreshed(page); }); } @@ -111,7 +112,9 @@ var page = this; - reload(page); + if (LibraryBrowser.needsRefresh(page)) { + reload(page); + } }); })(jQuery, document); \ No newline at end of file diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 89268335bf..37956c8b51 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -1844,6 +1844,7 @@ var AppInfo = {}; } else if ($.browser.safari) { Dashboard.importCss('themes/ios.css'); + Dashboard.importCss('thirdparty/materialicons/style.css'); } } diff --git a/dashboard-ui/themes/android.css b/dashboard-ui/themes/android.css index 37ca044216..2d4c5108df 100644 --- a/dashboard-ui/themes/android.css +++ b/dashboard-ui/themes/android.css @@ -17,3 +17,6 @@ .ui-page-theme-b .visualCardBox { background: rgba(56,56,56,.85); } +.libraryViewNav a{ + font-weight: 500; +} \ No newline at end of file diff --git a/dashboard-ui/thirdparty/emby-icons.html b/dashboard-ui/thirdparty/emby-icons.html index 3da06d0c74..bbf6e5f413 100644 --- a/dashboard-ui/thirdparty/emby-icons.html +++ b/dashboard-ui/thirdparty/emby-icons.html @@ -110,6 +110,7 @@ See [iron-iconset](#iron-iconset) and [iron-iconset-svg](#iron-iconset-svg) for + diff --git a/dashboard-ui/thirdparty/materialicons/style.css b/dashboard-ui/thirdparty/materialicons/style.css new file mode 100644 index 0000000000..713fdea9b1 --- /dev/null +++ b/dashboard-ui/thirdparty/materialicons/style.css @@ -0,0 +1,23 @@ +@font-face { + font-family: 'Material Icons'; + font-style: normal; + font-weight: 400; + src: url(MaterialIcons-Regular.eot); /* For IE6-8 */ + src: local('Material Icons'), local('MaterialIcons-Regular'), url(MaterialIcons-Regular.woff2) format('woff2'), url(MaterialIcons-Regular.woff) format('woff'), url(MaterialIcons-Regular.ttf) format('truetype'); +} + +.material-icons { + font-family: 'Material Icons'; + font-weight: normal; + font-style: normal; + display: inline-block; + text-transform: none; + /* Support for all WebKit browsers. */ + -webkit-font-smoothing: antialiased; + /* Support for Safari and Chrome. */ + text-rendering: optimizeLegibility; + /* Support for Firefox. */ + -moz-osx-font-smoothing: grayscale; + /* Support for IE. */ + font-feature-settings: 'liga'; +} \ No newline at end of file diff --git a/dashboard-ui/thirdparty/paper-button-style.css b/dashboard-ui/thirdparty/paper-button-style.css index 71782ae753..2316dc8b14 100644 --- a/dashboard-ui/thirdparty/paper-button-style.css +++ b/dashboard-ui/thirdparty/paper-button-style.css @@ -314,3 +314,40 @@ paper-fab.square { paper-slider { width: 100%; } + +paper-menu-item { + padding: .35em .5em; +} + +paper-menu-item iron-icon { + margin-right: 1.5em; +} +.actionSheetMenuItem { + cursor: pointer; +} +.actionSheetMenuItem:hover { + background: #eee; +} + +.scrollablePaperTabs paper-icon-button { + display: none !important; +} + +/*.scrollablePaperTabs #tabsContainer { + text-align: center; + overflow-x: scroll; + -webkit-overflow-scrolling: touch; + overflow-y: hidden; + white-space: nowrap; + -ms-overflow-style: none; + overflow: -moz-scrollbars-none; +} + +.scrollablePaperTabs #tabsContainer::-webkit-scrollbar { + height: 0 !important; + display: none; +} + +.scrollablePaperTabs #tabsContent { + position: static !important; +}*/ diff --git a/dashboard-ui/vulcanize-in.html b/dashboard-ui/vulcanize-in.html index 6846ec658a..6940ec073a 100644 --- a/dashboard-ui/vulcanize-in.html +++ b/dashboard-ui/vulcanize-in.html @@ -16,4 +16,5 @@ + \ No newline at end of file diff --git a/dashboard-ui/vulcanize-out.html b/dashboard-ui/vulcanize-out.html index 374ec86d46..2a60476b22 100644 --- a/dashboard-ui/vulcanize-out.html +++ b/dashboard-ui/vulcanize-out.html @@ -12057,6 +12057,8 @@ is separate from validation, and `allowed-pattern` does not affect how the input + +