diff --git a/dashboard-ui/bower_components/emby-webcomponents/lazyloader/lazyloader-intersectionobserver.js b/dashboard-ui/bower_components/emby-webcomponents/lazyloader/lazyloader-intersectionobserver.js new file mode 100644 index 0000000000..afeece3a80 --- /dev/null +++ b/dashboard-ui/bower_components/emby-webcomponents/lazyloader/lazyloader-intersectionobserver.js @@ -0,0 +1,87 @@ +define(['visibleinviewport', 'browser', 'dom'], function (visibleinviewport, browser, dom) { + 'use strict'; + + function LazyLoader(options) { + + this.options = options; + } + + LazyLoader.prototype.createObserver = function () { + + var observerOptions = {}; + var options = this.options; + var loadedCount = 0; + var callback = options.callback; + + //options.rootMargin = "300%"; + + var self = this; + var observer = new IntersectionObserver(function (entries) { + for (var j = 0, length2 = entries.length; j < length2; j++) { + var entry = entries[j]; + var target = entry.target; + observer.unobserve(target); + callback(target); + loadedCount++; + + if (loadedCount >= self.elementCount) { + self.destroyObserver(); + } + } + }, + observerOptions + ); + + this.observer = observer; + }; + + LazyLoader.prototype.addElements = function (elements) { + + var observer = this.observer; + + if (!observer) { + this.createObserver(); + observer = this.observer; + } + + this.elementCount = (this.elementCount || 0) + elements.length; + + for (var i = 0, length = elements.length; i < length; i++) { + observer.observe(elements[i]); + } + }; + + LazyLoader.prototype.destroyObserver = function (elements) { + + var observer = this.observer; + + if (observer) { + observer.disconnect(); + this.observer = null; + } + }; + + LazyLoader.prototype.destroy = function (elements) { + + this.destroyObserver(); + this.options = null; + }; + + function unveilElements(elements, root, callback) { + + if (!elements.length) { + return; + } + var lazyLoader = new LazyLoader({ + callback: callback + }); + lazyLoader.addElements(elements); + } + + LazyLoader.lazyChildren = function (elem, callback) { + + unveilElements(elem.getElementsByClassName('lazy'), elem, callback); + } + + return LazyLoader; +}); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/images/lazyloader.js b/dashboard-ui/bower_components/emby-webcomponents/lazyloader/lazyloader-scroll.js similarity index 73% rename from dashboard-ui/bower_components/emby-webcomponents/images/lazyloader.js rename to dashboard-ui/bower_components/emby-webcomponents/lazyloader/lazyloader-scroll.js index ed3f435a36..8d782b74f4 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/images/lazyloader.js +++ b/dashboard-ui/bower_components/emby-webcomponents/lazyloader/lazyloader-scroll.js @@ -8,16 +8,6 @@ define(['visibleinviewport', 'browser', 'dom'], function (visibleinviewport, bro fn(); }; - var supportsIntersectionObserver = function () { - - if (window.IntersectionObserver) { - - return true; - } - - return false; - }(); - function resetThresholds() { var x = screen.availWidth; @@ -32,11 +22,9 @@ define(['visibleinviewport', 'browser', 'dom'], function (visibleinviewport, bro thresholdY = y; } - if (!supportsIntersectionObserver) { - dom.addEventListener(window, "orientationchange", resetThresholds, { passive: true }); - dom.addEventListener(window, 'resize', resetThresholds, { passive: true }); - resetThresholds(); - } + dom.addEventListener(window, "orientationchange", resetThresholds, { passive: true }); + dom.addEventListener(window, 'resize', resetThresholds, { passive: true }); + resetThresholds(); function isVisible(elem) { return visibleinviewport(elem, true, thresholdX, thresholdY); @@ -52,50 +40,18 @@ define(['visibleinviewport', 'browser', 'dom'], function (visibleinviewport, bro } } - function unveilWithIntersection(elements, root, callback) { - - var filledCount = 0; - - var options = {}; - - //options.rootMargin = "300%"; - - var observer = new IntersectionObserver(function (entries) { - for (var j = 0, length2 = entries.length; j < length2; j++) { - var entry = entries[j]; - var target = entry.target; - observer.unobserve(target); - callback(target); - filledCount++; - } - }, - options - ); - // Start observing an element - for (var i = 0, length = elements.length; i < length; i++) { - observer.observe(elements[i]); - } - } - - function unveilElements(elements, root, callback) { - - if (!elements.length) { - return; - } - - if (supportsIntersectionObserver) { - unveilWithIntersection(elements, root, callback); - return; - } + function unveilElementsInternal(instance, callback) { var unveiledElements = []; var cancellationTokens = []; + var loadedCount = 0; function unveilInternal(tokenIndex) { var anyFound = false; var out = false; + var elements = instance.elements; // TODO: This out construct assumes left to right, top to bottom for (var i = 0, length = elements.length; i < length; i++) { @@ -111,6 +67,7 @@ define(['visibleinviewport', 'browser', 'dom'], function (visibleinviewport, bro anyFound = true; unveiledElements[i] = true; callback(elem); + loadedCount++; } else { if (anyFound) { @@ -119,7 +76,7 @@ define(['visibleinviewport', 'browser', 'dom'], function (visibleinviewport, bro } } - if (!elements.length) { + if (loadedCount >= elements.length) { dom.removeEventListener(document, 'focus', unveil, { capture: true, passive: true @@ -171,12 +128,58 @@ define(['visibleinviewport', 'browser', 'dom'], function (visibleinviewport, bro unveil(); } - function lazyChildren(elem, callback) { + function LazyLoader(options) { + + this.options = options; + } + + LazyLoader.prototype.createObserver = function () { + + unveilElementsInternal(this, this.options.callback); + this.observer = 1; + }; + + LazyLoader.prototype.addElements = function (elements) { + + this.elements = this.elements || []; + + for (var i = 0, length = elements.length; i < length; i++) { + this.elements.push(elements[i]); + } + + var observer = this.observer; + + if (!observer) { + this.createObserver(); + } + + }; + + LazyLoader.prototype.destroyObserver = function (elements) { + + }; + + LazyLoader.prototype.destroy = function (elements) { + + this.destroyObserver(); + this.options = null; + }; + + function unveilElements(elements, root, callback) { + + if (!elements.length) { + return; + } + var lazyLoader = new LazyLoader({ + callback: callback + }); + lazyLoader.addElements(elements); + } + + LazyLoader.lazyChildren = function (elem, callback) { unveilElements(elem.getElementsByClassName('lazy'), elem, callback); } - self.lazyChildren = lazyChildren; - - return self; + return LazyLoader; }); \ No newline at end of file diff --git a/dashboard-ui/bower_components/emby-webcomponents/usersettings/usersettingsbuilder.js b/dashboard-ui/bower_components/emby-webcomponents/usersettings/usersettingsbuilder.js index 0ddcf0b78c..31eca80476 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/usersettings/usersettingsbuilder.js +++ b/dashboard-ui/bower_components/emby-webcomponents/usersettings/usersettingsbuilder.js @@ -7,9 +7,14 @@ define(['appSettings', 'events', 'browser'], function (appsettings, events, brow var currentUserId; var currentApiClient; var displayPrefs; + var saveTimeout; self.setUserInfo = function (userId, apiClient) { + if (saveTimeout) { + clearTimeout(saveTimeout); + } + currentUserId = userId; currentApiClient = apiClient; @@ -24,7 +29,6 @@ define(['appSettings', 'events', 'browser'], function (appsettings, events, brow }); }; - var saveTimeout; function onSaveTimeout() { saveTimeout = null; currentApiClient.updateDisplayPreferences('usersettings', displayPrefs, currentUserId, 'emby'); diff --git a/dashboard-ui/scripts/indexpage.js b/dashboard-ui/scripts/indexpage.js index 5418e13cfc..0cc2e3e0c8 100644 --- a/dashboard-ui/scripts/indexpage.js +++ b/dashboard-ui/scripts/indexpage.js @@ -22,34 +22,32 @@ } } - function loadSection(page, user, displayPreferences, index) { + function loadSection(page, user, userSettings, index) { var userId = user.Id; - var section = displayPreferences.CustomPrefs['home' + index] || getDefaultSection(index); + var section = userSettings.get('homesection' + index) || getDefaultSection(index); if (section == 'folders') { section = defaultFirstSection; } - var showLibraryTileNames = displayPreferences.CustomPrefs.enableLibraryTileNames != '0'; - var elem = page.querySelector('.section' + index); if (section == 'latestmedia') { return Sections.loadRecentlyAdded(elem, user); } else if (section == 'librarytiles') { - return Sections.loadLibraryTiles(elem, user, 'backdrop', index, false, showLibraryTileNames); + return Sections.loadLibraryTiles(elem, user, 'backdrop', index, false); } else if (section == 'smalllibrarytiles') { - return Sections.loadLibraryTiles(elem, user, 'smallBackdrop', index, false, showLibraryTileNames); + return Sections.loadLibraryTiles(elem, user, 'smallBackdrop', index, false); } else if (section == 'smalllibrarytiles-automobile') { - return Sections.loadLibraryTiles(elem, user, 'smallBackdrop', index, true, showLibraryTileNames); + return Sections.loadLibraryTiles(elem, user, 'smallBackdrop', index, true); } else if (section == 'librarytiles-automobile') { - return Sections.loadLibraryTiles(elem, user, 'backdrop', index, true, showLibraryTileNames); + return Sections.loadLibraryTiles(elem, user, 'backdrop', index, true); } else if (section == 'librarybuttons') { return Sections.loadlibraryButtons(elem, userId, index); @@ -77,7 +75,7 @@ } } - function loadSections(page, user, displayPreferences) { + function loadSections(page, user, userSettings) { var i, length; var sectionCount = 5; @@ -98,7 +96,7 @@ for (i = 0, length = sectionCount; i < length; i++) { - promises.push(loadSection(page, user, displayPreferences, i)); + promises.push(loadSection(page, user, userSettings, i)); } return Promise.all(promises); @@ -186,24 +184,37 @@ }); } + function getRequirePromise(deps) { + + return new Promise(function (resolve, reject) { + + require(deps, resolve); + }); + } + function loadHomeTab(page, tabContent) { if (window.ApiClient) { var userId = Dashboard.getCurrentUserId(); Dashboard.showLoadingMsg(); - getDisplayPreferences('home', userId).then(function (result) { + var promises = [ + getDisplayPreferences('home', userId), + Dashboard.getCurrentUser(), + getRequirePromise(['userSettings']) + ]; - Dashboard.getCurrentUser().then(function (user) { + Promise.all(promises).then(function(responses) { + var displayPreferences = responses[0]; + var user = responses[1]; + var userSettings = responses[2]; - loadSections(tabContent, user, result).then(function () { - - if (!AppInfo.isNativeApp) { - showWelcomeIfNeeded(page, result); - } - Dashboard.hideLoadingMsg(); - }); + loadSections(tabContent, user, userSettings).then(function () { + if (!AppInfo.isNativeApp) { + showWelcomeIfNeeded(page, displayPreferences); + } + Dashboard.hideLoadingMsg(); }); }); } diff --git a/dashboard-ui/scripts/librarymenu.js b/dashboard-ui/scripts/librarymenu.js index edbb66aa02..589bb87dda 100644 --- a/dashboard-ui/scripts/librarymenu.js +++ b/dashboard-ui/scripts/librarymenu.js @@ -308,7 +308,7 @@ html += '
'; if (user.localUser && (AppInfo.isNativeApp && browserInfo.android)) { - html += 'settings '; + html += 'settings '; } html += 'file_download '; diff --git a/dashboard-ui/scripts/mypreferenceshome.js b/dashboard-ui/scripts/mypreferenceshome.js index 51c73177a1..872a97c7f4 100644 --- a/dashboard-ui/scripts/mypreferenceshome.js +++ b/dashboard-ui/scripts/mypreferenceshome.js @@ -1,4 +1,4 @@ -define(['listViewStyle'], function () { +define(['userSettingsBuilder', 'listViewStyle'], function (userSettingsBuilder) { 'use strict'; function renderViews(page, user, result) { @@ -113,14 +113,14 @@ page.querySelector('.viewOrderList').innerHTML = html; } - function loadForm(page, user, displayPreferences) { + function loadForm(page, user, userSettings) { page.querySelector('.chkHidePlayedFromLatest').checked = user.Configuration.HidePlayedInLatest || false; - page.querySelector('#selectHomeSection1').value = displayPreferences.CustomPrefs.home0 || ''; - page.querySelector('#selectHomeSection2').value = displayPreferences.CustomPrefs.home1 || ''; - page.querySelector('#selectHomeSection3').value = displayPreferences.CustomPrefs.home2 || ''; - page.querySelector('#selectHomeSection4').value = displayPreferences.CustomPrefs.home3 || ''; + page.querySelector('#selectHomeSection1').value = userSettings.get('homesection0') || ''; + page.querySelector('#selectHomeSection2').value = userSettings.get('homesection1') || ''; + page.querySelector('#selectHomeSection3').value = userSettings.get('homesection2') || ''; + page.querySelector('#selectHomeSection4').value = userSettings.get('homesection3') || ''; var promise1 = ApiClient.getUserViews({}, user.Id); var promise2 = ApiClient.getJSON(ApiClient.getUrl("Users/" + user.Id + "/GroupingOptions")); @@ -135,14 +135,6 @@ }); } - function displayPreferencesKey() { - if (AppInfo.isNativeApp) { - return 'Emby Mobile'; - } - - return 'webclient'; - } - function getCheckboxItems(selector, page, isChecked) { var inputs = page.querySelectorAll(selector); @@ -159,7 +151,7 @@ return list; } - function saveUser(page, user, displayPreferences) { + function saveUser(page, user, userSettings) { user.Configuration.HidePlayedInLatest = page.querySelector('.chkHidePlayedFromLatest').checked; @@ -183,18 +175,15 @@ user.Configuration.OrderedViews = orderedViews; - displayPreferences.CustomPrefs.home0 = page.querySelector('#selectHomeSection1').value; - displayPreferences.CustomPrefs.home1 = page.querySelector('#selectHomeSection2').value; - displayPreferences.CustomPrefs.home2 = page.querySelector('#selectHomeSection3').value; - displayPreferences.CustomPrefs.home3 = page.querySelector('#selectHomeSection4').value; + userSettings.set('homesection0', page.querySelector('#selectHomeSection1').value); + userSettings.set('homesection1', page.querySelector('#selectHomeSection2').value); + userSettings.set('homesection2', page.querySelector('#selectHomeSection3').value); + userSettings.set('homesection3', page.querySelector('#selectHomeSection4').value); - return ApiClient.updateDisplayPreferences('home', displayPreferences, user.Id, displayPreferencesKey()).then(function () { - - return ApiClient.updateUserConfiguration(user.Id, user.Configuration); - }); + return ApiClient.updateUserConfiguration(user.Id, user.Configuration); } - function save(page, userId) { + function save(page, userId, userSettings) { Dashboard.showLoadingMsg(); @@ -204,21 +193,17 @@ ApiClient.getUser(userId).then(function (user) { - ApiClient.getDisplayPreferences('home', user.Id, displayPreferencesKey()).then(function (displayPreferences) { + saveUser(page, user, userSettings).then(function () { - saveUser(page, user, displayPreferences).then(function () { - - Dashboard.hideLoadingMsg(); - if (!AppInfo.enableAutoSave) { - require(['toast'], function (toast) { - toast(Globalize.translate('SettingsSaved')); - }); - } - - }, function () { - Dashboard.hideLoadingMsg(); - }); + Dashboard.hideLoadingMsg(); + if (!AppInfo.enableAutoSave) { + require(['toast'], function (toast) { + toast(Globalize.translate('SettingsSaved')); + }); + } + }, function () { + Dashboard.hideLoadingMsg(); }); }); } @@ -257,14 +242,21 @@ return function (view, params) { - var userId = getParameterByName('userId') || Dashboard.getCurrentUserId(); + var userId = params.userId || Dashboard.getCurrentUserId(); + var userSettings = new userSettingsBuilder(); + var userSettingsLoaded; function onSubmit(e) { - save(view, userId); + userSettings.setUserInfo(userId, ApiClient).then(function () { + + save(view, userId, userSettings); + }); // Disable default form submission - e.preventDefault(); + if (e) { + e.preventDefault(); + } return false; } @@ -329,19 +321,18 @@ ApiClient.getUser(userId).then(function (user) { - ApiClient.getDisplayPreferences('home', user.Id, displayPreferencesKey()).then(function (result) { + userSettings.setUserInfo(userId, ApiClient).then(function () { - loadForm(page, user, result); + userSettingsLoaded = true; + loadForm(page, user, userSettings); }); }); }); view.addEventListener('viewbeforehide', function () { - var page = this; - if (AppInfo.enableAutoSave) { - save(page, userId); + onSubmit(); } }); }; diff --git a/dashboard-ui/scripts/sections.js b/dashboard-ui/scripts/sections.js index dcea2f867f..5d52377e7c 100644 --- a/dashboard-ui/scripts/sections.js +++ b/dashboard-ui/scripts/sections.js @@ -388,7 +388,7 @@ }); } - function loadLibraryTiles(elem, user, shape, index, autoHideOnMobile, showTitles) { + function loadLibraryTiles(elem, user, shape, index, autoHideOnMobile) { return getUserViews(user.Id).then(function (items) { @@ -418,7 +418,7 @@ html += cardBuilder.getCardsHtml({ items: items, shape: scrollX ? 'overflowBackdrop' : shape, - showTitle: showTitles, + showTitle: true, centerText: true, overlayText: false, lazy: true, diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index a4dd21af98..f88739d3fc 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -314,7 +314,7 @@ var Dashboard = { showUserFlyout: function () { - Dashboard.navigate('mypreferencesmenu.html?userId=' + ApiClient.getCurrentUserId()); + Dashboard.navigate('mypreferencesmenu.html'); }, getPluginSecurityInfo: function () { @@ -1222,7 +1222,11 @@ var AppInfo = {}; define("libjass", [bowerPath + "/libjass/libjass.min", "css!" + bowerPath + "/libjass/libjass"], returnFirstDependency); - define("lazyLoader", [embyWebComponentsBowerPath + "/images/lazyloader"], returnFirstDependency); + if (window.IntersectionObserver) { + define("lazyLoader", [embyWebComponentsBowerPath + "/lazyloader/lazyloader-intersectionobserver"], returnFirstDependency); + } else { + define("lazyLoader", [embyWebComponentsBowerPath + "/lazyloader/lazyloader-scroll"], returnFirstDependency); + } define("imageLoader", [embyWebComponentsBowerPath + "/images/imagehelper"], returnFirstDependency); define("syncJobList", ["components/syncjoblist/syncjoblist"], returnFirstDependency); define("appfooter", ["components/appfooter/appfooter"], returnFirstDependency); @@ -1543,7 +1547,7 @@ var AppInfo = {}; }; embyRouter.showSettings = function () { - Dashboard.navigate('mypreferencesmenu.html?userId=' + ApiClient.getCurrentUserId()); + Dashboard.navigate('mypreferencesmenu.html'); }; embyRouter.showGuide = function () {