From b6fc490b89846c6dea7584cff4fae4cd86857eda Mon Sep 17 00:00:00 2001
From: Mark McDowall <markus.mcd5@gmail.com>
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<EpisodeFileDeletedEvent>,
                                 IHandle<SeriesUpdatedEvent>,       
                                 IHandle<SeriesEditedEvent>,  
-                                IHandle<SeriesDeletedEvent>
-                                
+                                IHandle<SeriesDeletedEvent>,
+                                IHandle<SeriesRenamedEvent>
+
     {
         private readonly ISeriesService _seriesService;
         private readonly ISeriesStatisticsService _seriesStatisticsService;
@@ -207,5 +208,10 @@ namespace NzbDrone.Api.Series
         {
             BroadcastResourceChange(ModelAction.Deleted, message.Series.InjectTo<SeriesResource>());
         }
+
+        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'));
             }
         });
     });