When a new episode is grabbed the client will update its status

This commit is contained in:
Mark McDowall 2013-08-10 11:38:01 -07:00
parent bcb13f93ff
commit c1b68e0dee
7 changed files with 101 additions and 18 deletions

View File

@ -0,0 +1,24 @@
using System;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Infrastructure;
using NzbDrone.Api.SignalR;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.Download;
using NzbDrone.Core.Tv;
namespace NzbDrone.Api.Episodes
{
public class EpisodeConnection : BasicResourceConnection<Episode>, IHandleAsync<EpisodeGrabbedEvent>
{
public override string Resource
{
get { return "/Episodes"; }
}
public void HandleAsync(EpisodeGrabbedEvent message)
{
var context = ((ConnectionManager)GlobalHost.ConnectionManager).GetConnection(GetType());
context.Connection.Broadcast(message);
}
}
}

View File

@ -89,6 +89,7 @@
<Compile Include="Directories\DirectoryModule.cs" />
<Compile Include="Episodes\EpisodeModule.cs" />
<Compile Include="Episodes\EpisodeResource.cs" />
<Compile Include="Episodes\EpisodeConnection.cs" />
<Compile Include="Extensions\CacheHeaderPipeline.cs" />
<Compile Include="Extensions\GZipPipeline.cs" />
<Compile Include="Extensions\NancyJsonSerializer.cs" />

View File

@ -40,7 +40,12 @@ define(
return this;
}
else {
if (!this.model.get('airDateUtc')) {
if (this.model.get('downloading')) {
icon = 'icon-download-alt';
tooltip = 'Episode is downloading';
}
else if (!this.model.get('airDateUtc')) {
icon = 'icon-question-sign';
tooltip = 'TBA';
}

View File

@ -6,11 +6,13 @@ define(
_.extend(Backbone.Collection.prototype, {BindSignalR: function (options) {
if (!options || !options.url) {
if (!options) {
options = {};
}
if (!options.url) {
console.assert(this.url, 'url must be provided or collection must have url');
options = {
url: this.url.replace('api', 'signalr')
};
options['url'] = this.url.replace('api', 'signalr');
}
var self = this;
@ -31,16 +33,24 @@ define(
};
var connection = $.connection(options.url);
connection.stateChanged(function (change) {
console.debug('{0} [{1}]'.format(options.url, _getStatus(change.newState)));
});
connection.received(function (model) {
console.debug(model);
self.fetch();
connection.received(function (message) {
console.debug(message);
if (options.onReceived) {
var context = options.context || self;
options.onReceived.call(context, message);
}
else {
self.fetch();
}
});
connection.start({ transport:

View File

@ -23,7 +23,22 @@ define(
episodeCollection: this.episodeCollection,
series : this.series
};
}
},
onEpisodeGrabbed: function (message) {
if (message.episode.series.id != this.episodeCollection.seriesId) {
return;
}
var self = this;
_.each(message.episode.episodes, function (episode){
var ep = self.episodeCollection.find({ id: episode.id });
ep.set('downloading', true);
console.debug(episode.title);
});
this.render();
}
});
});

View File

@ -9,7 +9,8 @@ define(
'Series/Details/SeasonMenu/CollectionView',
'Shared/LoadingView',
'Shared/Actioneer',
'backstrech'
'backstrech',
'Mixins/backbone.signalr.mixin'
], function (App, Marionette, EpisodeCollection, SeasonCollection, SeasonCollectionView, SeasonMenuCollectionView, LoadingView, Actioneer) {
return Marionette.Layout.extend({
@ -156,14 +157,21 @@ define(
this.seasons.show(new LoadingView());
this.seasonCollection = new SeasonCollection();
this.episodeCollection = new EpisodeCollection();
this.episodeCollection = new EpisodeCollection({ seriesId: this.model.id });
$.when(this.episodeCollection.fetch({data: { seriesId: this.model.id }}), this.seasonCollection.fetch({data: { seriesId: this.model.id }})).done(function () {
self.seasons.show(new SeasonCollectionView({
$.when(this.episodeCollection.fetch(), this.seasonCollection.fetch({data: { seriesId: this.model.id }})).done(function () {
var seasonCollectionView = new SeasonCollectionView({
collection : self.seasonCollection,
episodeCollection: self.episodeCollection,
series : self.model
}));
});
self.episodeCollection.BindSignalR({
onReceived: seasonCollectionView.onEpisodeGrabbed,
context : seasonCollectionView
});
self.seasons.show(seasonCollectionView);
self.seasonMenu.show(new SeasonMenuCollectionView({
collection: self.seasonCollection,

View File

@ -8,6 +8,17 @@ define(
url : window.ApiRoot + '/episodes',
model: EpisodeModel,
state: {
sortKey: 'episodeNumber',
order : -1
},
originalFetch: Backbone.Collection.prototype.fetch,
initialize: function (options) {
this.seriesId = options.seriesId;
},
bySeason: function (season) {
var filtered = this.filter(function (episode) {
return episode.get('seasonNumber') === season;
@ -34,9 +45,18 @@ define(
return 0;
},
state: {
sortKey: 'episodeNumber',
order : -1
fetch: function (options) {
if (!this.seriesId) {
throw 'seriesId is required';
}
if (!options) {
options = {};
}
options['data'] = { seriesId: this.seriesId };
return this.originalFetch.call(this, options);
}
});
});