diff --git a/web/directives/plex-library.js b/web/directives/plex-library.js index c906a62..2e32c3f 100644 --- a/web/directives/plex-library.js +++ b/web/directives/plex-library.js @@ -13,7 +13,17 @@ module.exports = function (plex, dizquetv, $timeout) { if ( typeof(scope.limit) == 'undefined') { scope.limit = 1000000000; } + scope.pending = 0; + scope.allowedIndexes = []; + for (let i = -10; i <= -1; i++) { + scope.allowedIndexes.push(i); + } scope.selection = [] + scope.wait = (t) => { + return new Promise((resolve, reject) => { + $timeout(resolve,t); + }); + } scope.selectServer = function (server) { scope.plexServer = server updateLibrary(server) @@ -31,15 +41,36 @@ module.exports = function (plex, dizquetv, $timeout) { scope.visible = false } } - scope.selectItem = (item) => { - return new Promise((resolve, reject) => { - $timeout(async () => { - item.streams = await plex.getStreams(scope.plexServer, item.key) - scope.selection.push(JSON.parse(angular.toJson(item))) - scope.$apply() - resolve() - }, 0) - }) + scope.selectItem = async (item, single) => { + await scope.wait(0); + scope.pending += 1; + try { + item.streams = await plex.getStreams(scope.plexServer, item.key) + scope.selection.push(JSON.parse(angular.toJson(item))) + } finally { + scope.pending -= 1; + } + if (single) { + scope.$apply() + } + } + scope.selectLibrary = async (library) => { + await scope.fillNestedIfNecessary(library); + let p = library.nested.length; + scope.pending += library.nested.length; + try { + for (let i = 0; i < library.nested.length; i++) { + //await scope.selectItem( library.nested[i] ); + if (library.nested[i].type !== 'collection') { + await scope.selectShow( library.nested[i] ); + } + scope.pending -= 1; + p -= 1; + } + } finally { + scope.pending -= p; + scope.$apply() + } } dizquetv.getPlexServers().then((servers) => { if (servers.length === 0) { @@ -66,10 +97,14 @@ module.exports = function (plex, dizquetv, $timeout) { console.log(err) }) } - scope.getNested = (list) => { + scope.fillNestedIfNecessary = async (x, isLibrary) => { + if ( (typeof(x.nested) === 'undefined') && (x.type !== 'collection') ) { + x.nested = await plex.getNested(scope.plexServer, x.key, isLibrary); + } + } + scope.getNested = (list, isLibrary) => { $timeout(async () => { - if (typeof list.nested === 'undefined') - list.nested = await plex.getNested(scope.plexServer, list.key) + await scope.fillNestedIfNecessary(list, isLibrary); list.collapse = !list.collapse scope.$apply() }, 0) @@ -78,34 +113,53 @@ module.exports = function (plex, dizquetv, $timeout) { scope.selectSeason = (season) => { return new Promise((resolve, reject) => { $timeout(async () => { - if (typeof season.nested === 'undefined') - season.nested = await plex.getNested(scope.plexServer, season.key) - for (let i = 0, l = season.nested.length; i < l; i++) - await scope.selectItem(season.nested[i]) - scope.$apply() - resolve() + await scope.fillNestedIfNecessary(season); + let p = season.nested.length; + scope.pending += p; + try { + for (let i = 0, l = season.nested.length; i < l; i++) { + await scope.selectItem(season.nested[i], false) + scope.pending -= 1; + p -= 1; + } + resolve(); + } catch (e) { + reject(e); + } finally { + scope.pending -= p; + scope.$apply() + } }, 0) }) } scope.selectShow = (show) => { return new Promise((resolve, reject) => { $timeout(async () => { - if (typeof show.nested === 'undefined') - show.nested = await plex.getNested(scope.plexServer, show.key) - for (let i = 0, l = show.nested.length; i < l; i++) - await scope.selectSeason(show.nested[i]) - scope.$apply() - resolve() + await scope.fillNestedIfNecessary(show); + let p = show.nested.length; + scope.pending += p; + try { + for (let i = 0, l = show.nested.length; i < l; i++) { + await scope.selectSeason(show.nested[i]) + scope.pending -= 1; + p -= 1; + } + resolve(); + } catch (e) { + reject(e); + } finally { + scope.pending -= p; + scope.$apply() + } }, 0) }) } scope.selectPlaylist = async (playlist) => { return new Promise((resolve, reject) => { $timeout(async () => { - if (typeof playlist.nested === 'undefined') - playlist.nested = await plex.getNested(scope.plexServer, playlist.key) + await scope.fillNestedIfNecessary(playlist); for (let i = 0, l = playlist.nested.length; i < l; i++) - await scope.selectItem(playlist.nested[i]) + await scope.selectItem(playlist.nested[i], false) scope.$apply() resolve() }, 0) diff --git a/web/public/style.css b/web/public/style.css index 23d50e8..8c58dcc 100644 --- a/web/public/style.css +++ b/web/public/style.css @@ -72,6 +72,7 @@ font-size: 80%; font-weight: 400; font-family: monospace; + white-space: nowrap; } .program-row { align-items: start; @@ -92,4 +93,26 @@ font-size: .875rem; line-height: 1.0; margin-right: 0.5rem; +} + +.loader { + width: 1em; + height: 1em; + border: 0.3em solid #f3f3f3; + border-radius: 50%; + display: inline-block; + border-top: 0.25em solid #3498db; + -webkit-animation: spin 2s linear infinite; /* Safari */ + animation: spin 2s linear infinite; +} + +/* Safari */ +@-webkit-keyframes spin { + 0% { -webkit-transform: rotate(0deg); } + 100% { -webkit-transform: rotate(360deg); } +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } } \ No newline at end of file diff --git a/web/public/templates/plex-library.html b/web/public/templates/plex-library.html index 2a47d17..4270bce 100644 --- a/web/public/templates/plex-library.html +++ b/web/public/templates/plex-library.html @@ -33,16 +33,19 @@