From 0c63e5ad81bdae533a63a6c89e5333d82fe49361 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Sat, 1 Jun 2013 12:31:39 -0700 Subject: [PATCH] episodes for series are now fetched using a single call and broken into seasons. --- NzbDrone.Api/Episodes/EpisodeModule.cs | 8 +---- UI/Content/base.less | 26 +++++++++++--- UI/Controller.js | 4 +-- UI/Series/Details/SeasonCollectionView.js | 24 +++++++++++++ UI/Series/Details/SeasonLayout.js | 15 ++++---- UI/Series/Details/SeriesDetailsLayout.js | 36 ++++++++++++++++++++ UI/Series/Details/SeriesDetailsTemplate.html | 5 ++- UI/Series/Details/SeriesDetailsView.js | 20 ----------- UI/Series/EpisodeCollection.js | 10 +++++- UI/Series/series.less | 7 +++- UI/Shared/LoadingTemplate.html | 1 + UI/Shared/LoadingView.js | 10 ++++++ 12 files changed, 119 insertions(+), 47 deletions(-) create mode 100644 UI/Series/Details/SeasonCollectionView.js create mode 100644 UI/Series/Details/SeriesDetailsLayout.js delete mode 100644 UI/Series/Details/SeriesDetailsView.js create mode 100644 UI/Shared/LoadingTemplate.html create mode 100644 UI/Shared/LoadingView.js diff --git a/NzbDrone.Api/Episodes/EpisodeModule.cs b/NzbDrone.Api/Episodes/EpisodeModule.cs index 5dda07586..befa69c1c 100644 --- a/NzbDrone.Api/Episodes/EpisodeModule.cs +++ b/NzbDrone.Api/Episodes/EpisodeModule.cs @@ -19,19 +19,13 @@ namespace NzbDrone.Api.Episodes private List GetEpisodes() { var seriesId = (int?)Request.Query.SeriesId; - var seasonNumber = (int?)Request.Query.SeasonNumber; if (seriesId == null) { throw new BadRequestException("seriesId is missing"); } - if (seasonNumber == null) - { - return ToListResource(() => _episodeService.GetEpisodeBySeries(seriesId.Value)); - } - - return ToListResource(() => _episodeService.GetEpisodesBySeason(seriesId.Value, seasonNumber.Value)); + return ToListResource(() => _episodeService.GetEpisodeBySeries(seriesId.Value)); } } } \ No newline at end of file diff --git a/UI/Content/base.less b/UI/Content/base.less index ce5ff5c37..734d76987 100644 --- a/UI/Content/base.less +++ b/UI/Content/base.less @@ -1,4 +1,6 @@ -.progress { +@import "bootstrap/bootstrap"; + +.progress { width: 125px; position: relative; margin-bottom: 2px; @@ -20,20 +22,24 @@ overflow: hidden; } } + html { overflow: -moz-scrollbars-vertical; overflow-y: scroll; } + .input-append { .add-on { margin-left: 0; } } + .line &>[class^="icon-"], .line &>[class*=" icon-"] { margin-top: 1em; height: 1em; line-height: 1em; } + #localSeriesLookup { width: 220px; border: 0px; @@ -42,6 +48,7 @@ html { padding: 4px; font-size: 13px; } + #footer-region { font-size: 16px; text-decoration: none; @@ -51,11 +58,13 @@ html { text-decoration: underline; } } + #in-sub-nav { ul { margin: 0 0 80px 0; } } + #notification-region { pre { font-size: 12px; @@ -67,14 +76,21 @@ html { padding-right: 10px; } } + +.nz-loading { + .text-center; + font-size: 40px; + font-weight: 300; + padding: 30px; +} + .nz-spinner { + .text-center; font-size: 56px; - text-align: center; padding: 30px; } - -.page-toolbar{ +.page-toolbar { margin-top: 10px; margin-bottom: 30px; } @@ -89,4 +105,4 @@ button::-moz-focus-inner, a::-moz-focus-inner { a:focus { outline: none; -} \ No newline at end of file +} diff --git a/UI/Controller.js b/UI/Controller.js index 42f5dd575..bbca914cb 100644 --- a/UI/Controller.js +++ b/UI/Controller.js @@ -7,7 +7,7 @@ define(['app', 'Shared/NotificationView', 'Shared/NotFoundView', 'MainMenuView', - 'Series/Details/SeriesDetailsView', + 'Series/Details/SeriesDetailsLayout', 'Series/EpisodeCollection', 'Settings/SettingsLayout', 'Missing/MissingLayout', @@ -27,7 +27,7 @@ define(['app', series.fetch({ success: function (seriesModel) { self._setTitle(seriesModel.get('title')); - NzbDrone.mainRegion.show(new NzbDrone.Series.Details.SeriesDetailsView({ model: seriesModel })); + NzbDrone.mainRegion.show(new NzbDrone.Series.Details.SeriesDetailsLayout({ model: seriesModel })); } }); }, diff --git a/UI/Series/Details/SeasonCollectionView.js b/UI/Series/Details/SeasonCollectionView.js new file mode 100644 index 000000000..5550790a5 --- /dev/null +++ b/UI/Series/Details/SeasonCollectionView.js @@ -0,0 +1,24 @@ +"use strict"; +define(['app', 'Series/Details/SeasonLayout', 'Series/SeasonCollection', 'Series/EpisodeCollection'], function () { + NzbDrone.Series.Details.SeasonCollectionView = Backbone.Marionette.CollectionView.extend({ + + itemView : NzbDrone.Series.Details.SeasonLayout, + + initialize: function (options) { + + if (!options.episodeCollection) { + throw 'episodeCollection is needed'; + } + + this.episodeCollection = options.episodeCollection; + + }, + + itemViewOptions: function () { + return { + episodeCollection: this.episodeCollection + }; + } + + }); +}); diff --git a/UI/Series/Details/SeasonLayout.js b/UI/Series/Details/SeasonLayout.js index 79a6125d2..c7c15b259 100644 --- a/UI/Series/Details/SeasonLayout.js +++ b/UI/Series/Details/SeasonLayout.js @@ -36,23 +36,22 @@ define(['app', 'Series/Details/EpisodeStatusCell', 'Series/Details/EpisodeTitleC } ], - initialize: function () { - this.episodeCollection = new NzbDrone.Series.EpisodeCollection(); - this.episodeCollection.fetch({data: { - seriesId : this.model.get('seriesId'), - seasonNumber: this.model.get('seasonNumber') - }}); + initialize: function (options) { + + if (!options.episodeCollection) { + throw 'episodeCollection is needed'; + } + + this.episodeCollection = options.episodeCollection.bySeason(this.model.get('seasonNumber')); }, onShow: function () { - this.episodeGrid.show(new Backgrid.Grid( { columns : this.columns, collection: this.episodeCollection, className : 'table table-hover' })); - } }); }); diff --git a/UI/Series/Details/SeriesDetailsLayout.js b/UI/Series/Details/SeriesDetailsLayout.js new file mode 100644 index 000000000..4fc077b4d --- /dev/null +++ b/UI/Series/Details/SeriesDetailsLayout.js @@ -0,0 +1,36 @@ +"use strict"; +define(['app', 'Series/Details/SeasonCollectionView','Shared/LoadingView'], function () { + NzbDrone.Series.Details.SeriesDetailsLayout = Backbone.Marionette.Layout.extend({ + + itemViewContainer: '.x-series-seasons', + template : 'Series/Details/SeriesDetailsTemplate', + + regions: { + seasons: '#seasons' + }, + + onShow: function () { + + var self = this; + + this.seasons.show(new NzbDrone.Shared.LoadingView()); + + this.seasonCollection = new NzbDrone.Series.SeasonCollection(); + this.episodeCollection = new NzbDrone.Series.EpisodeCollection(); + + $.when(this.episodeCollection.fetch({data: { seriesId: this.model.id }}), this.seasonCollection.fetch({data: { seriesId: this.model.id }})) + .done(function () { + self.seasons.show(new NzbDrone.Series.Details.SeasonCollectionView({ + collection : self.seasonCollection, + episodeCollection: self.episodeCollection + })); + } + ); + }, + + onClose: function () { + $('.backstretch').remove(); + } + }); + } +); diff --git a/UI/Series/Details/SeriesDetailsTemplate.html b/UI/Series/Details/SeriesDetailsTemplate.html index be3ea84ec..8a4cd2615 100644 --- a/UI/Series/Details/SeriesDetailsTemplate.html +++ b/UI/Series/Details/SeriesDetailsTemplate.html @@ -1,4 +1,4 @@ - - -
+
diff --git a/UI/Series/Details/SeriesDetailsView.js b/UI/Series/Details/SeriesDetailsView.js deleted file mode 100644 index 4779cabcc..000000000 --- a/UI/Series/Details/SeriesDetailsView.js +++ /dev/null @@ -1,20 +0,0 @@ -"use strict"; -define(['app', 'Quality/QualityProfileCollection', 'Series/Details/SeasonLayout', 'Series/SeasonCollection'], function () { - NzbDrone.Series.Details.SeriesDetailsView = Backbone.Marionette.CompositeView.extend({ - - itemView : NzbDrone.Series.Details.SeasonLayout, - itemViewContainer: '.x-series-seasons', - template : 'Series/Details/SeriesDetailsTemplate', - - initialize: function () { - this.collection = new NzbDrone.Series.SeasonCollection(); - this.collection.fetch({data: { seriesId: this.model.get('id') }}); - - //$.backstretch(this.model.get('fanArt')); - }, - - onClose: function(){ - $('.backstretch').remove(); - } - }); -}); diff --git a/UI/Series/EpisodeCollection.js b/UI/Series/EpisodeCollection.js index 7312b7806..636ab6d15 100644 --- a/UI/Series/EpisodeCollection.js +++ b/UI/Series/EpisodeCollection.js @@ -2,6 +2,14 @@ define(['app', 'Series/EpisodeModel'], function () { NzbDrone.Series.EpisodeCollection = Backbone.Collection.extend({ url : NzbDrone.Constants.ApiRoot + '/episodes', - model: NzbDrone.Series.EpisodeModel + model: NzbDrone.Series.EpisodeModel, + + bySeason: function (season) { + var filtered = this.filter(function (episode) { + return episode.get("seasonNumber") === season; + }); + + return new NzbDrone.Series.EpisodeCollection(filtered); + } }); }); diff --git a/UI/Series/series.less b/UI/Series/series.less index 77e5dafa9..564414e08 100644 --- a/UI/Series/series.less +++ b/UI/Series/series.less @@ -111,4 +111,9 @@ display: none; } } -} \ No newline at end of file + +} + +.series-detail-summary { + margin-bottom: 50px; +} diff --git a/UI/Shared/LoadingTemplate.html b/UI/Shared/LoadingTemplate.html new file mode 100644 index 000000000..76a55ea86 --- /dev/null +++ b/UI/Shared/LoadingTemplate.html @@ -0,0 +1 @@ +loading ... diff --git a/UI/Shared/LoadingView.js b/UI/Shared/LoadingView.js new file mode 100644 index 000000000..fa0cd21a8 --- /dev/null +++ b/UI/Shared/LoadingView.js @@ -0,0 +1,10 @@ +"use strict"; + +define(['app'], function () { + NzbDrone.Shared.LoadingView = Backbone.Marionette.ItemView.extend({ + template : 'Shared/LoadingTemplate', + className: 'nz-loading row' + }); +}); + +