From b6fc490b89846c6dea7584cff4fae4cd86857eda Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 6 Nov 2014 07:34:15 -0800 Subject: [PATCH] Series detials fixes Fixed: Adding a new series and going to series details will show data after information is fetched Fixed: Series details won't reload view after update --- src/NzbDrone.Api/Series/SeriesModule.cs | 10 ++- src/UI/Mixins/backbone.signalr.mixin.js | 2 +- src/UI/Series/Details/SeasonCollectionView.js | 21 +++++++ src/UI/Series/Details/SeasonLayout.js | 23 ++++--- src/UI/Series/Details/SeriesDetailsLayout.js | 61 ++++++++++++------- src/UI/Series/SeasonModel.js | 4 ++ 6 files changed, 87 insertions(+), 34 deletions(-) diff --git a/src/NzbDrone.Api/Series/SeriesModule.cs b/src/NzbDrone.Api/Series/SeriesModule.cs index 01711efd9..1b20364e0 100644 --- a/src/NzbDrone.Api/Series/SeriesModule.cs +++ b/src/NzbDrone.Api/Series/SeriesModule.cs @@ -24,8 +24,9 @@ namespace NzbDrone.Api.Series IHandle, IHandle, IHandle, - IHandle - + IHandle, + IHandle + { private readonly ISeriesService _seriesService; private readonly ISeriesStatisticsService _seriesStatisticsService; @@ -207,5 +208,10 @@ namespace NzbDrone.Api.Series { BroadcastResourceChange(ModelAction.Deleted, message.Series.InjectTo()); } + + public void Handle(SeriesRenamedEvent message) + { + BroadcastResourceChange(ModelAction.Updated, message.Series.Id); + } } } diff --git a/src/UI/Mixins/backbone.signalr.mixin.js b/src/UI/Mixins/backbone.signalr.mixin.js index 72e0e7108..ee64ba7a3 100644 --- a/src/UI/Mixins/backbone.signalr.mixin.js +++ b/src/UI/Mixins/backbone.signalr.mixin.js @@ -35,7 +35,7 @@ define( return; } - collection.add(model, {merge: true}); + collection.add(model, {merge: true, changeSource: 'signalr'}); console.log(options.action + ': {0}}'.format(options.resource)); }; diff --git a/src/UI/Series/Details/SeasonCollectionView.js b/src/UI/Series/Details/SeasonCollectionView.js index d3fde1b24..ab165d6de 100644 --- a/src/UI/Series/Details/SeasonCollectionView.js +++ b/src/UI/Series/Details/SeasonCollectionView.js @@ -19,6 +19,27 @@ define( this.series = options.series; }, + appendHtml: function(collectionView, itemView, index) { + var childrenContainer = collectionView.itemViewContainer ? collectionView.$(collectionView.itemViewContainer) : collectionView.$el; + var collection = collectionView.collection; + + // If the index of the model is at the end of the collection append, else insert at proper index + if (index >= collection.size() - 1) { + childrenContainer.append(itemView.el); + } else { + var previousModel = collection.at(index + 1); + var previousView = this.children.findByModel(previousModel); + + if (previousView) { + previousView.$el.before(itemView.$el); + } + + else { + childrenContainer.append(itemView.el); + } + } + }, + itemViewOptions: function () { return { episodeCollection: this.episodeCollection, diff --git a/src/UI/Series/Details/SeasonLayout.js b/src/UI/Series/Details/SeasonLayout.js index cafec8d23..6aea66c09 100644 --- a/src/UI/Series/Details/SeasonLayout.js +++ b/src/UI/Series/Details/SeasonLayout.js @@ -105,20 +105,17 @@ define( throw 'episodeCollection is needed'; } - this.episodeCollection = options.episodeCollection.bySeason(this.model.get('seasonNumber')); - - var self = this; - - this.episodeCollection.each(function (model) { - model.episodeCollection = self.episodeCollection; - }); - this.series = options.series; + this.fullEpisodeCollection = options.episodeCollection; + this.episodeCollection = this.fullEpisodeCollection.bySeason(this.model.get('seasonNumber')); + this._updateEpisodeCollection(); this.showingEpisodes = this._shouldShowEpisodes(); this.listenTo(this.model, 'sync', this._afterSeasonMonitored); this.listenTo(this.episodeCollection, 'sync', this.render); + + this.listenTo(this.fullEpisodeCollection, 'sync', this._updateEpisodeCollection); }, onRender: function () { @@ -293,6 +290,16 @@ define( var range = _.range(low + 1, high); this.episodeCollection.lastToggled = model; + }, + + _updateEpisodeCollection: function () { + var self = this; + + this.episodeCollection.add(this.fullEpisodeCollection.bySeason(this.model.get('seasonNumber')).models, { merge: true }); + + this.episodeCollection.each(function (model) { + model.episodeCollection = self.episodeCollection; + }); } }); }); diff --git a/src/UI/Series/Details/SeriesDetailsLayout.js b/src/UI/Series/Details/SeriesDetailsLayout.js index 553c6a828..628d4cda2 100644 --- a/src/UI/Series/Details/SeriesDetailsLayout.js +++ b/src/UI/Series/Details/SeriesDetailsLayout.js @@ -7,6 +7,7 @@ define( 'reqres', 'marionette', 'backbone', + 'Series/SeriesCollection', 'Series/EpisodeCollection', 'Series/EpisodeFileCollection', 'Series/SeasonCollection', @@ -22,6 +23,7 @@ define( reqres, Marionette, Backbone, + SeriesCollection, EpisodeCollection, EpisodeFileCollection, SeasonCollection, @@ -57,9 +59,18 @@ define( }, initialize: function () { + this.seriesCollection = SeriesCollection.clone(); + this.seriesCollection.shadowCollection.bindSignalR(); + this.listenTo(this.model, 'change:monitored', this._setMonitoredState); - this.listenTo(vent, vent.Events.SeriesDeleted, this._onSeriesDeleted); + this.listenTo(this.model, 'remove', this._seriesRemoved); this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete); + + this.listenTo(this.model, 'change', function (model, options) { + if (options && options.changeSource === 'signalr') { + this._refresh(); + } + }); }, onShow: function () { @@ -96,23 +107,13 @@ define( CommandController.bindToCommand({ element: this.ui.rename, command: { - name : 'renameFiles', - seriesId : this.model.id, - seasonNumber: -1 + name : 'renameFiles', + seriesId : this.model.id, + seasonNumber : -1 } }); }, - _getFanArt: function () { - var fanArt = _.where(this.model.get('images'), {coverType: 'fanart'}); - - if (fanArt && fanArt[0]) { - return fanArt[0].url; - } - - return undefined; - }, - onClose: function () { if (this._backstrech) { @@ -124,6 +125,16 @@ define( reqres.removeHandler(reqres.Requests.GetEpisodeFileById); }, + _getFanArt: function () { + var fanArt = _.where(this.model.get('images'), {coverType: 'fanart'}); + + if (fanArt && fanArt[0]) { + return fanArt[0].url; + } + + return undefined; + }, + _toggleMonitored: function () { var savePromise = this.model.save('monitored', !this.model.get('monitored'), { wait: true @@ -160,11 +171,8 @@ define( }); }, - _onSeriesDeleted: function (event) { - - if (this.model.get('id') === event.series.get('id')) { - Backbone.history.navigate('/', { trigger: true }); - } + _seriesRemoved: function () { + Backbone.history.navigate('/', { trigger: true }); }, _renameSeries: function () { @@ -215,13 +223,20 @@ define( }, _commandComplete: function (options) { - if (options.command.get('name') === 'refreshseries' || options.command.get('name') === 'renamefiles') { + if (options.command.get('name') === 'renamefiles') { if (options.command.get('seriesId') === this.model.get('id')) { - this._showSeasons(); - this._setMonitoredState(); - this._showInfo(); + this._refresh(); } } + }, + + _refresh: function () { + this.seasonCollection.add(this.model.get('seasons'), { merge: true }); + this.episodeCollection.fetch(); + this.episodeFileCollection.fetch(); + + this._setMonitoredState(); + this._showInfo(); } }); }); diff --git a/src/UI/Series/SeasonModel.js b/src/UI/Series/SeasonModel.js index 7a30af04b..049c3b5a1 100644 --- a/src/UI/Series/SeasonModel.js +++ b/src/UI/Series/SeasonModel.js @@ -7,6 +7,10 @@ define( defaults: { seasonNumber: 0 + }, + + initialize: function () { + this.set('id', this.get('seasonNumber')); } }); });