mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-17 15:02:34 +02:00
Fixed: Multiple Calendar Issues, Other UI Fixes (#2685)
Fixes #2683 Fixes #1172 Fixes #563
This commit is contained in:
parent
00877ad361
commit
a2fa8c4594
@ -20,12 +20,6 @@ var QueueCollection = PageableCollection.extend({
|
|||||||
|
|
||||||
mode : 'client',
|
mode : 'client',
|
||||||
|
|
||||||
findEpisode : function(episodeId) {
|
|
||||||
return _.find(this.fullCollection.models, function(queueModel) {
|
|
||||||
return queueModel.get('episode').id === episodeId;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
findMovie : function(movieId) {
|
findMovie : function(movieId) {
|
||||||
return _.find(this.fullCollection.models, function(queueModel) {
|
return _.find(this.fullCollection.models, function(queueModel) {
|
||||||
return queueModel.get('movie').id === movieId;
|
return queueModel.get('movie').id === movieId;
|
||||||
@ -33,14 +27,6 @@ var QueueCollection = PageableCollection.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
sortMappings : {
|
sortMappings : {
|
||||||
series : {
|
|
||||||
sortValue : function(model, attr) {
|
|
||||||
var series = model.get(attr);
|
|
||||||
|
|
||||||
return series.get('sortTitle');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
movie : {
|
movie : {
|
||||||
sortValue : function(model, attr) {
|
sortValue : function(model, attr) {
|
||||||
var movie = model.get(attr);
|
var movie = model.get(attr);
|
||||||
@ -49,22 +35,6 @@ var QueueCollection = PageableCollection.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
episode : {
|
|
||||||
sortValue : function(model, attr) {
|
|
||||||
var episode = model.get('episode');
|
|
||||||
|
|
||||||
return FormatHelpers.pad(episode.get('seasonNumber'), 4) + FormatHelpers.pad(episode.get('episodeNumber'), 4);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
episodeTitle : {
|
|
||||||
sortValue : function(model, attr) {
|
|
||||||
var episode = model.get('episode');
|
|
||||||
|
|
||||||
return episode.get('title');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
timeleft : {
|
timeleft : {
|
||||||
sortValue : function(model, attr) {
|
sortValue : function(model, attr) {
|
||||||
var eta = model.get('estimatedCompletionTime');
|
var eta = model.get('estimatedCompletionTime');
|
||||||
|
@ -2,8 +2,6 @@ var Marionette = require('marionette');
|
|||||||
var Backgrid = require('backgrid');
|
var Backgrid = require('backgrid');
|
||||||
var QueueCollection = require('./QueueCollection');
|
var QueueCollection = require('./QueueCollection');
|
||||||
var MovieTitleCell = require('../../Cells/MovieTitleCell');
|
var MovieTitleCell = require('../../Cells/MovieTitleCell');
|
||||||
var EpisodeNumberCell = require('../../Cells/EpisodeNumberCell');
|
|
||||||
var EpisodeTitleCell = require('../../Cells/EpisodeTitleCell');
|
|
||||||
var QualityCell = require('../../Cells/QualityCell');
|
var QualityCell = require('../../Cells/QualityCell');
|
||||||
var QueueStatusCell = require('./QueueStatusCell');
|
var QueueStatusCell = require('./QueueStatusCell');
|
||||||
var QueueActionsCell = require('./QueueActionsCell');
|
var QueueActionsCell = require('./QueueActionsCell');
|
||||||
@ -32,17 +30,6 @@ module.exports = Marionette.Layout.extend({
|
|||||||
label : 'Movie',
|
label : 'Movie',
|
||||||
cell : MovieTitleCell
|
cell : MovieTitleCell
|
||||||
},
|
},
|
||||||
/*{
|
|
||||||
name : 'episode',
|
|
||||||
label : 'Episode',
|
|
||||||
cell : EpisodeNumberCell
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name : 'episodeTitle',
|
|
||||||
label : 'Episode Title',
|
|
||||||
cell : EpisodeTitleCell,
|
|
||||||
cellValue : 'episode'
|
|
||||||
},*/
|
|
||||||
{
|
{
|
||||||
name : 'quality',
|
name : 'quality',
|
||||||
label : 'Quality',
|
label : 'Quality',
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
var Backbone = require('backbone');
|
var Backbone = require('backbone');
|
||||||
var EpisodeModel = require('../Movies/MovieModel');
|
var MovieModel = require('../Movies/MovieModel');
|
||||||
|
|
||||||
module.exports = Backbone.Collection.extend({
|
module.exports = Backbone.Collection.extend({
|
||||||
url : window.NzbDrone.ApiRoot + '/calendar',
|
url : window.NzbDrone.ApiRoot + '/calendar',
|
||||||
model : EpisodeModel,
|
model : MovieModel,
|
||||||
tableName : 'calendar',
|
tableName : 'calendar',
|
||||||
|
|
||||||
comparator : function(model) {
|
comparator : function(model) {
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
var vent = require('vent');
|
var vent = require('vent');
|
||||||
var Marionette = require('marionette');
|
var Marionette = require('marionette');
|
||||||
|
var AppLayout = require('../AppLayout');
|
||||||
var moment = require('moment');
|
var moment = require('moment');
|
||||||
var CalendarCollection = require('./CalendarCollection');
|
var CalendarCollection = require('./CalendarCollection');
|
||||||
var UiSettings = require('../Shared/UiSettingsModel');
|
var UiSettings = require('../Shared/UiSettingsModel');
|
||||||
var QueueCollection = require('../Activity/Queue/QueueCollection');
|
var QueueCollection = require('../Activity/Queue/QueueCollection');
|
||||||
|
var MoviesDetailsLayout = require('../Movies/Details/MoviesDetailsLayout');
|
||||||
var Config = require('../Config');
|
var Config = require('../Config');
|
||||||
|
|
||||||
require('../Mixins/backbone.signalr.mixin');
|
require('../Mixins/backbone.signalr.mixin');
|
||||||
@ -89,7 +91,7 @@ module.exports = Marionette.ItemView.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
element.find('.chart').tooltip({
|
element.find('.chart').tooltip({
|
||||||
title : 'Episode is downloading - {0}% {1}'.format(progress.toFixed(1), releaseTitle),
|
title : 'Movie is downloading - {0}% {1}'.format(progress.toFixed(1), releaseTitle),
|
||||||
container : '.fc'
|
container : '.fc'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -144,7 +146,7 @@ module.exports = Marionette.ItemView.extend({
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
collection.each(function(model) {
|
collection.each(function(model) {
|
||||||
var seriesTitle = model.get('title');
|
var movieTitle = model.get('title');
|
||||||
var start = model.get('inCinemas');
|
var start = model.get('inCinemas');
|
||||||
var startDate = new Date(start);
|
var startDate = new Date(start);
|
||||||
if (!(startD <= startDate && startDate <= endD)) {
|
if (!(startD <= startDate && startDate <= endD)) {
|
||||||
@ -154,14 +156,15 @@ module.exports = Marionette.ItemView.extend({
|
|||||||
var end = moment(start).add(runtime, 'minutes').toISOString();
|
var end = moment(start).add(runtime, 'minutes').toISOString();
|
||||||
|
|
||||||
var event = {
|
var event = {
|
||||||
title : seriesTitle,
|
title : movieTitle,
|
||||||
start : moment(start),
|
start : moment(start),
|
||||||
end : moment(end),
|
end : moment(end),
|
||||||
allDay : true,
|
allDay : true,
|
||||||
statusLevel : self._getStatusLevel(model, end),
|
statusLevel : self._getStatusLevel(model, end),
|
||||||
downloading : QueueCollection.findMovie(model.get('id')),
|
downloading : QueueCollection.findMovie(model.get('id')),
|
||||||
model : model,
|
model : model,
|
||||||
sortOrder : 0
|
sortOrder : 0,
|
||||||
|
url : "movies/" + model.get("titleSlug")
|
||||||
};
|
};
|
||||||
|
|
||||||
events.push(event);
|
events.push(event);
|
||||||
@ -229,11 +232,7 @@ module.exports = Marionette.ItemView.extend({
|
|||||||
viewRender : this._viewRender.bind(this),
|
viewRender : this._viewRender.bind(this),
|
||||||
eventRender : this._eventRender.bind(this),
|
eventRender : this._eventRender.bind(this),
|
||||||
eventAfterAllRender : this._eventAfterAllRender.bind(this),
|
eventAfterAllRender : this._eventAfterAllRender.bind(this),
|
||||||
windowResize : this._windowResize.bind(this),
|
windowResize : this._windowResize.bind(this)
|
||||||
eventClick : function(event) {
|
|
||||||
//vent.trigger(vent.Commands.ShowMovieDetails, { movie : event.model });
|
|
||||||
window.location.href = "movies/"+event.model.get("titleSlug");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if ($(window).width() < 768) {
|
if ($(window).width() < 768) {
|
||||||
@ -256,13 +255,16 @@ module.exports = Marionette.ItemView.extend({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
options.titleFormat = "L";
|
options.views = {
|
||||||
|
month: {
|
||||||
options.columnFormat = "L"; /*{
|
titleFormat: 'MMMM YYYY',
|
||||||
month : 'ddd',
|
columnFormat: 'ddd'
|
||||||
week : UiSettings.get('calendarWeekColumnHeader'),
|
},
|
||||||
day : 'dddd'
|
list: {
|
||||||
};*///For now ignore settings. TODO update that.
|
titleFormat: 'L',
|
||||||
|
columnFormat: 'L'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
options.timeFormat = UiSettings.get('timeFormat');
|
options.timeFormat = UiSettings.get('timeFormat');
|
||||||
|
|
||||||
|
@ -1,17 +1,29 @@
|
|||||||
var Backbone = require('backbone');
|
var Backbone = require('backbone');
|
||||||
var moment = require('moment');
|
var moment = require('moment');
|
||||||
var EpisodeModel = require('../Movies/MovieModel');
|
var MovieModel = require('../Movies/MovieModel');
|
||||||
|
|
||||||
module.exports = Backbone.Collection.extend({
|
module.exports = Backbone.Collection.extend({
|
||||||
url : window.NzbDrone.ApiRoot + '/calendar',
|
url : window.NzbDrone.ApiRoot + '/calendar',
|
||||||
model : EpisodeModel,
|
model : MovieModel,
|
||||||
|
|
||||||
comparator : function(model1, model2) {
|
comparator : function(model1, model2) {
|
||||||
|
|
||||||
var airDate1 = model1.get('inCinemas');
|
var airDate1 = model1.get('inCinemas');
|
||||||
|
var airDate2 = model2.get('inCinemas');
|
||||||
|
var status1 = model1.get('status');
|
||||||
|
var status2 = model2.get('status');
|
||||||
|
|
||||||
|
if (status1 === 'inCinemas') {
|
||||||
|
airDate1 = model1.get('physicalRelease');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status2 === 'inCinemas') {
|
||||||
|
airDate2 = model2.get('physicalRelease');
|
||||||
|
}
|
||||||
|
|
||||||
var date1 = moment(airDate1);
|
var date1 = moment(airDate1);
|
||||||
var time1 = date1.unix();
|
var time1 = date1.unix();
|
||||||
|
|
||||||
var airDate2 = model2.get('inCinemas');
|
|
||||||
var date2 = moment(airDate2);
|
var date2 = moment(airDate2);
|
||||||
var time2 = date2.unix();
|
var time2 = date2.unix();
|
||||||
|
|
||||||
|
@ -6,23 +6,7 @@ module.exports = Marionette.ItemView.extend({
|
|||||||
template : 'Calendar/UpcomingItemViewTemplate',
|
template : 'Calendar/UpcomingItemViewTemplate',
|
||||||
tagName : 'div',
|
tagName : 'div',
|
||||||
|
|
||||||
events : {
|
|
||||||
'click .x-episode-title' : '_showEpisodeDetails'
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize : function() {
|
initialize : function() {
|
||||||
var start = this.model.get('inCinemas');
|
|
||||||
var runtime = this.model.get('runtime');
|
|
||||||
var end = moment(start).add(runtime, 'minutes');
|
|
||||||
|
|
||||||
this.model.set({
|
|
||||||
end : end.toISOString()
|
|
||||||
});
|
|
||||||
|
|
||||||
this.listenTo(this.model, 'change', this.render);
|
this.listenTo(this.model, 'change', this.render);
|
||||||
},
|
|
||||||
|
|
||||||
_showEpisodeDetails : function() {
|
|
||||||
vent.trigger(vent.Commands.ShowEpisodeDetails, { episode : this.model });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
<div class="event">
|
<div class="event">
|
||||||
<div class="date {{StatusLevel}}">
|
<div class="date {{StatusLevel}}">
|
||||||
<h1>{{Day airDateUtc}}</h1>
|
{{#if_eq status compare="announced"}}
|
||||||
<h4>{{Month airDateUtc}}</h4>
|
<h1>{{Day inCinemas}}</h1>
|
||||||
|
<h4>{{Month inCinemas}}</h4>
|
||||||
|
{{else}}
|
||||||
|
<h1>{{Day physicalRelease}}</h1>
|
||||||
|
<h4>{{Month physicalRelease}}</h4>
|
||||||
|
{{/if_eq}}
|
||||||
</div>
|
</div>
|
||||||
{{#with series}}
|
|
||||||
<a href="{{route}}">
|
<a href="{{route}}">
|
||||||
<h4>{{title}}</h4>
|
<h4>{{title}}</h4>
|
||||||
</a>
|
</a>
|
||||||
{{/with}}
|
|
||||||
<p>{{StartTime airDateUtc}} {{#unless_today airDateUtc}}{{ShortDate airDateUtc}}{{/unless_today}}</p>
|
|
||||||
<p>
|
|
||||||
<span class="episode-title x-episode-title">
|
|
||||||
{{title}}
|
|
||||||
</span>
|
|
||||||
<span class="pull-right">{{seasonNumber}}x{{Pad2 episodeNumber}}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -96,7 +96,6 @@
|
|||||||
|
|
||||||
.primary {
|
.primary {
|
||||||
border-color : @btn-primary-bg;
|
border-color : @btn-primary-bg;
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
var Marionette = require('marionette');
|
|
||||||
var NzbDroneCell = require('./NzbDroneCell');
|
|
||||||
|
|
||||||
module.exports = NzbDroneCell.extend({
|
|
||||||
className : 'episode-progress-cell',
|
|
||||||
template : 'Cells/EpisodeProgressCellTemplate',
|
|
||||||
|
|
||||||
render : function() {
|
|
||||||
|
|
||||||
var episodeCount = this.model.get('episodeCount');
|
|
||||||
var episodeFileCount = this.model.get('episodeFileCount');
|
|
||||||
|
|
||||||
var percent = 100;
|
|
||||||
|
|
||||||
if (episodeCount > 0) {
|
|
||||||
percent = episodeFileCount / episodeCount * 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.model.set('percentOfEpisodes', percent);
|
|
||||||
|
|
||||||
this.templateFunction = Marionette.TemplateCache.get(this.template);
|
|
||||||
var data = this.model.toJSON();
|
|
||||||
var html = this.templateFunction(data);
|
|
||||||
this.$el.html(html);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
});
|
|
@ -1 +0,0 @@
|
|||||||
{{> EpisodeProgressPartial }}
|
|
@ -1,127 +0,0 @@
|
|||||||
var reqres = require('../reqres');
|
|
||||||
var Backbone = require('backbone');
|
|
||||||
var NzbDroneCell = require('./NzbDroneCell');
|
|
||||||
var QueueCollection = require('../Activity/Queue/QueueCollection');
|
|
||||||
var moment = require('moment');
|
|
||||||
var FormatHelpers = require('../Shared/FormatHelpers');
|
|
||||||
|
|
||||||
module.exports = NzbDroneCell.extend({
|
|
||||||
className : 'episode-status-cell',
|
|
||||||
|
|
||||||
render : function() {
|
|
||||||
this.listenTo(QueueCollection, 'sync', this._renderCell);
|
|
||||||
|
|
||||||
this._renderCell();
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
_renderCell : function() {
|
|
||||||
|
|
||||||
if (this.episodeFile) {
|
|
||||||
this.stopListening(this.episodeFile, 'change', this._refresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$el.empty();
|
|
||||||
|
|
||||||
if (this.model) {
|
|
||||||
|
|
||||||
var icon;
|
|
||||||
var tooltip;
|
|
||||||
|
|
||||||
var hasAired = moment(this.model.get('airDateUtc')).isBefore(moment());
|
|
||||||
this.episodeFile = this._getFile();
|
|
||||||
|
|
||||||
if (this.episodeFile) {
|
|
||||||
this.listenTo(this.episodeFile, 'change', this._refresh);
|
|
||||||
|
|
||||||
var quality = this.episodeFile.get('quality');
|
|
||||||
var revision = quality.revision;
|
|
||||||
var size = FormatHelpers.bytes(this.episodeFile.get('size'));
|
|
||||||
var title = 'Episode downloaded';
|
|
||||||
|
|
||||||
if (revision.real && revision.real > 0) {
|
|
||||||
title += '[REAL]';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (revision.version && revision.version > 1) {
|
|
||||||
title += ' [PROPER]';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size !== '') {
|
|
||||||
title += ' - {0}'.format(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.episodeFile.get('qualityCutoffNotMet')) {
|
|
||||||
this.$el.html('<span class="badge badge-inverse" title="{0}">{1}</span>'.format(title, quality.quality.name));
|
|
||||||
} else {
|
|
||||||
this.$el.html('<span class="badge" title="{0}">{1}</span>'.format(title, quality.quality.name));
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
var model = this.model;
|
|
||||||
var downloading = QueueCollection.findEpisode(model.get('id'));
|
|
||||||
|
|
||||||
if (downloading) {
|
|
||||||
var progress = 100 - (downloading.get('sizeleft') / downloading.get('size') * 100);
|
|
||||||
|
|
||||||
if (progress === 0) {
|
|
||||||
icon = 'icon-sonarr-downloading';
|
|
||||||
tooltip = 'Episode is downloading';
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
this.$el.html('<div class="progress" title="Episode is downloading - {0}% {1}">'.format(progress.toFixed(1), downloading.get('title')) +
|
|
||||||
'<div class="progress-bar progress-bar-purple" style="width: {0}%;"></div></div>'.format(progress));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (this.model.get('grabbed')) {
|
|
||||||
icon = 'icon-sonarr-downloading';
|
|
||||||
tooltip = 'Episode is downloading';
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (!this.model.get('airDateUtc')) {
|
|
||||||
icon = 'icon-sonarr-tba';
|
|
||||||
tooltip = 'TBA';
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (hasAired) {
|
|
||||||
icon = 'icon-sonarr-missing';
|
|
||||||
tooltip = 'Episode missing from disk';
|
|
||||||
} else {
|
|
||||||
icon = 'icon-sonarr-not-aired';
|
|
||||||
tooltip = 'Episode has not aired';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$el.html('<i class="{0}" title="{1}"/>'.format(icon, tooltip));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getFile : function() {
|
|
||||||
var hasFile = this.model.get('hasFile');
|
|
||||||
|
|
||||||
if (hasFile) {
|
|
||||||
var episodeFile;
|
|
||||||
|
|
||||||
if (reqres.hasHandler(reqres.Requests.GetEpisodeFileById)) {
|
|
||||||
episodeFile = reqres.request(reqres.Requests.GetEpisodeFileById, this.model.get('episodeFileId'));
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (this.model.has('episodeFile')) {
|
|
||||||
episodeFile = new Backbone.Model(this.model.get('episodeFile'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (episodeFile) {
|
|
||||||
return episodeFile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,29 +0,0 @@
|
|||||||
var vent = require('vent');
|
|
||||||
var NzbDroneCell = require('./NzbDroneCell');
|
|
||||||
|
|
||||||
module.exports = NzbDroneCell.extend({
|
|
||||||
className : 'episode-title-cell',
|
|
||||||
|
|
||||||
events : {
|
|
||||||
'click' : '_showDetails'
|
|
||||||
},
|
|
||||||
|
|
||||||
render : function() {
|
|
||||||
var title = this.cellValue.get('title');
|
|
||||||
|
|
||||||
if (!title || title === '') {
|
|
||||||
title = 'TBA';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$el.html(title);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
_showDetails : function() {
|
|
||||||
var hideSeriesLink = this.column.get('hideSeriesLink');
|
|
||||||
vent.trigger(vent.Commands.ShowEpisodeDetails, {
|
|
||||||
episode : this.cellValue,
|
|
||||||
hideSeriesLink : hideSeriesLink
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,66 +0,0 @@
|
|||||||
var Handlebars = require('handlebars');
|
|
||||||
var FormatHelpers = require('../../Shared/FormatHelpers');
|
|
||||||
var moment = require('moment');
|
|
||||||
require('../../Activity/Queue/QueueCollection');
|
|
||||||
|
|
||||||
Handlebars.registerHelper('EpisodeNumber', function() {
|
|
||||||
|
|
||||||
if (this.series.seriesType === 'daily') {
|
|
||||||
return moment(this.airDate).format('L');
|
|
||||||
} else if (this.series.seriesType === 'anime' && this.absoluteEpisodeNumber !== undefined) {
|
|
||||||
return '{0}x{1} ({2})'.format(this.seasonNumber, FormatHelpers.pad(this.episodeNumber, 2), FormatHelpers.pad(this.absoluteEpisodeNumber, 2));
|
|
||||||
} else {
|
|
||||||
return '{0}x{1}'.format(this.seasonNumber, FormatHelpers.pad(this.episodeNumber, 2));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('StatusLevel', function() {
|
|
||||||
var hasFile = this.hasFile;
|
|
||||||
var downloading = require('../../Activity/Queue/QueueCollection').findEpisode(this.id) || this.downloading;
|
|
||||||
var currentTime = moment();
|
|
||||||
var start = moment(this.airDateUtc);
|
|
||||||
var end = moment(this.end);
|
|
||||||
var monitored = this.series.monitored && this.monitored;
|
|
||||||
|
|
||||||
if (hasFile) {
|
|
||||||
return 'success';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (downloading) {
|
|
||||||
return 'purple';
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (!monitored) {
|
|
||||||
return 'unmonitored';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.episodeNumber === 1) {
|
|
||||||
return 'premiere';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentTime.isAfter(start) && currentTime.isBefore(end)) {
|
|
||||||
return 'warning';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start.isBefore(currentTime) && !hasFile) {
|
|
||||||
return 'danger';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'primary';
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('EpisodeProgressClass', function() {
|
|
||||||
if (this.episodeFileCount === this.episodeCount) {
|
|
||||||
if (this.status === 'continuing') {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'progress-bar-success';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.monitored) {
|
|
||||||
return 'progress-bar-danger';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'progress-bar-warning';
|
|
||||||
});
|
|
@ -1,6 +1,73 @@
|
|||||||
var Handlebars = require('handlebars');
|
var Handlebars = require('handlebars');
|
||||||
var StatusModel = require('../../System/StatusModel');
|
var StatusModel = require('../../System/StatusModel');
|
||||||
|
var FormatHelpers = require('../../Shared/FormatHelpers');
|
||||||
|
var moment = require('moment');
|
||||||
var _ = require('underscore');
|
var _ = require('underscore');
|
||||||
|
require('../../Activity/Queue/QueueCollection');
|
||||||
|
|
||||||
|
Handlebars.registerHelper('GetStatus', function() {
|
||||||
|
var monitored = this.monitored;
|
||||||
|
var status = this.status;
|
||||||
|
//var inCinemas = this.inCinemas;
|
||||||
|
//var date = new Date(inCinemas);
|
||||||
|
//var timeSince = new Date().getTime() - date.getTime();
|
||||||
|
//var numOfMonths = timeSince / 1000 / 60 / 60 / 24 / 30;
|
||||||
|
|
||||||
|
|
||||||
|
if (status === "announced") {
|
||||||
|
return new Handlebars.SafeString('<i class="icon-sonarr-movie-announced grid-icon" title=""></i> Announced');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (status ==="inCinemas") {
|
||||||
|
return new Handlebars.SafeString('<i class="icon-sonarr-movie-cinemas grid-icon" title=""></i> In Cinemas');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'released') {
|
||||||
|
return new Handlebars.SafeString('<i class="icon-sonarr-movie-released grid-icon" title=""></i> Released');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!monitored) {
|
||||||
|
return new Handlebars.SafeString('<i class="icon-sonarr-series-unmonitored grid-icon" title=""></i> Not Monitored');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Handlebars.registerHelper('route', function() {
|
||||||
|
return StatusModel.get('urlBase') + '/movies/' + this.titleSlug;
|
||||||
|
});
|
||||||
|
|
||||||
|
Handlebars.registerHelper('StatusLevel', function() {
|
||||||
|
var hasFile = this.hasFile;
|
||||||
|
var downloading = require('../../Activity/Queue/QueueCollection').findMovie(this.id) || this.downloading;
|
||||||
|
var currentTime = moment();
|
||||||
|
var monitored = this.monitored;
|
||||||
|
|
||||||
|
if (hasFile) {
|
||||||
|
return 'success';
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (downloading) {
|
||||||
|
return 'purple';
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (!monitored) {
|
||||||
|
return 'unmonitored';
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (this.status === "inCinemas") {
|
||||||
|
return 'premiere';
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (this.status === "released") {
|
||||||
|
return 'danger';
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (this.status === "announced") {
|
||||||
|
return 'primary';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'primary';
|
||||||
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('poster', function() {
|
Handlebars.registerHelper('poster', function() {
|
||||||
|
|
||||||
@ -75,33 +142,6 @@ Handlebars.registerHelper('alternativeTitlesString', function() {
|
|||||||
return '"' + titles.slice(0,titles.length-1).join('", "') + '" and "' + titles[titles.length-1] + '"';
|
return '"' + titles.slice(0,titles.length-1).join('", "') + '" and "' + titles[titles.length-1] + '"';
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('GetStatus', function() {
|
|
||||||
var monitored = this.monitored;
|
|
||||||
var status = this.status;
|
|
||||||
//var inCinemas = this.inCinemas;
|
|
||||||
//var date = new Date(inCinemas);
|
|
||||||
//var timeSince = new Date().getTime() - date.getTime();
|
|
||||||
//var numOfMonths = timeSince / 1000 / 60 / 60 / 24 / 30;
|
|
||||||
|
|
||||||
|
|
||||||
if (status === "announced") {
|
|
||||||
return new Handlebars.SafeString('<i class="icon-sonarr-movie-announced grid-icon" title=""></i> Announced');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (status ==="inCinemas") {
|
|
||||||
return new Handlebars.SafeString('<i class="icon-sonarr-movie-cinemas grid-icon" title=""></i> In Cinemas');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'released') {
|
|
||||||
return new Handlebars.SafeString('<i class="icon-sonarr-movie-released grid-icon" title=""></i> Released');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!monitored) {
|
|
||||||
return new Handlebars.SafeString('<i class="icon-sonarr-series-unmonitored grid-icon" title=""></i> Not Monitored');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('GetBannerStatus', function() {
|
Handlebars.registerHelper('GetBannerStatus', function() {
|
||||||
var monitored = this.monitored;
|
var monitored = this.monitored;
|
||||||
var status = this.status;
|
var status = this.status;
|
||||||
@ -161,7 +201,6 @@ Handlebars.registerHelper("DownloadedQuality", function() {
|
|||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Handlebars.registerHelper('inCinemas', function() {
|
Handlebars.registerHelper('inCinemas', function() {
|
||||||
var monthNames = ["January", "February", "March", "April", "May", "June",
|
var monthNames = ["January", "February", "March", "April", "May", "June",
|
||||||
"July", "August", "September", "October", "November", "December"
|
"July", "August", "September", "October", "November", "December"
|
||||||
@ -184,46 +223,6 @@ Handlebars.registerHelper('inCinemas', function() {
|
|||||||
return "To be announced";
|
return "To be announced";
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('tvRageUrl', function() {
|
|
||||||
return 'http://www.tvrage.com/shows/id-' + this.tvRageId;
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('tvMazeUrl', function() {
|
|
||||||
return 'http://www.tvmaze.com/shows/' + this.tvMazeId + '/_';
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('route', function() {
|
|
||||||
return StatusModel.get('urlBase') + '/movies/' + this.titleSlug;
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('percentOfEpisodes', function() {
|
|
||||||
var episodeCount = this.episodeCount;
|
|
||||||
var episodeFileCount = this.episodeFileCount;
|
|
||||||
|
|
||||||
var percent = 100;
|
|
||||||
|
|
||||||
if (episodeCount > 0) {
|
|
||||||
percent = episodeFileCount / episodeCount * 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
return percent;
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('seasonCountHelper', function() {
|
|
||||||
var seasonCount = this.seasonCount;
|
|
||||||
var continuing = this.status === 'continuing';
|
|
||||||
|
|
||||||
if (continuing) {
|
|
||||||
return new Handlebars.SafeString('<span class="label label-info">Season {0}</span>'.format(seasonCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seasonCount === 1) {
|
|
||||||
return new Handlebars.SafeString('<span class="label label-info">{0} Season</span>'.format(seasonCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Handlebars.SafeString('<span class="label label-info">{0} Seasons</span>'.format(seasonCount));
|
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('titleWithYear', function() {
|
Handlebars.registerHelper('titleWithYear', function() {
|
||||||
if (this.title.endsWith(' ({0})'.format(this.year))) {
|
if (this.title.endsWith(' ({0})'.format(this.year))) {
|
||||||
return this.title;
|
return this.title;
|
||||||
@ -234,4 +233,4 @@ Handlebars.registerHelper('titleWithYear', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new Handlebars.SafeString('{0} <span class="year">({1})</span>'.format(this.title, this.year));
|
return new Handlebars.SafeString('{0} <span class="year">({1})</span>'.format(this.title, this.year));
|
||||||
});
|
});
|
@ -3,8 +3,7 @@ require('handlebars.helpers');
|
|||||||
require('./Helpers/DateTime');
|
require('./Helpers/DateTime');
|
||||||
require('./Helpers/Html');
|
require('./Helpers/Html');
|
||||||
require('./Helpers/Numbers');
|
require('./Helpers/Numbers');
|
||||||
require('./Helpers/Episode');
|
require('./Helpers/Movie');
|
||||||
require('./Helpers/Series');
|
|
||||||
require('./Helpers/Quality');
|
require('./Helpers/Quality');
|
||||||
require('./Helpers/System');
|
require('./Helpers/System');
|
||||||
require('./Helpers/EachReverse');
|
require('./Helpers/EachReverse');
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
var Marionette = require('marionette');
|
|
||||||
var NzbDroneCell = require('../../Cells/NzbDroneCell');
|
|
||||||
var reqres = require('../../reqres');
|
|
||||||
var SeriesCollection = require('../SeriesCollection');
|
|
||||||
|
|
||||||
module.exports = NzbDroneCell.extend({
|
|
||||||
className : 'episode-number-cell',
|
|
||||||
template : 'Movies/Details/EpisodeNumberCellTemplate',
|
|
||||||
|
|
||||||
render : function() {
|
|
||||||
this.$el.empty();
|
|
||||||
this.$el.html(this.model.get('episodeNumber'));
|
|
||||||
|
|
||||||
var series = SeriesCollection.get(this.model.get('seriesId'));
|
|
||||||
|
|
||||||
if (series.get('seriesType') === 'anime' && this.model.has('absoluteEpisodeNumber')) {
|
|
||||||
this.$el.html('{0} ({1})'.format(this.model.get('episodeNumber'), this.model.get('absoluteEpisodeNumber')));
|
|
||||||
}
|
|
||||||
|
|
||||||
var alternateTitles = [];
|
|
||||||
|
|
||||||
if (reqres.hasHandler(reqres.Requests.GetAlternateNameBySeasonNumber)) {
|
|
||||||
alternateTitles = reqres.request(reqres.Requests.GetAlternateNameBySeasonNumber, this.model.get('seriesId'), this.model.get('seasonNumber'), this.model.get('sceneSeasonNumber'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.model.get('sceneSeasonNumber') > 0 || this.model.get('sceneEpisodeNumber') > 0 || this.model.has('sceneAbsoluteEpisodeNumber') || alternateTitles.length > 0) {
|
|
||||||
this.templateFunction = Marionette.TemplateCache.get(this.template);
|
|
||||||
|
|
||||||
var json = this.model.toJSON();
|
|
||||||
json.alternateTitles = alternateTitles;
|
|
||||||
|
|
||||||
var html = this.templateFunction(json);
|
|
||||||
|
|
||||||
this.$el.popover({
|
|
||||||
content : html,
|
|
||||||
html : true,
|
|
||||||
trigger : 'hover',
|
|
||||||
title : 'Scene Information',
|
|
||||||
placement : 'right',
|
|
||||||
container : this.$el
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.delegateEvents();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,39 +0,0 @@
|
|||||||
<div class="scene-info">
|
|
||||||
{{#if sceneSeasonNumber}}
|
|
||||||
<div class="row">
|
|
||||||
<div class="key">Season</div>
|
|
||||||
<div class="value">{{sceneSeasonNumber}}</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if sceneEpisodeNumber}}
|
|
||||||
<div class="row">
|
|
||||||
<div class="key">Episode</div>
|
|
||||||
<div class="value">{{sceneEpisodeNumber}}</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if sceneAbsoluteEpisodeNumber}}
|
|
||||||
<div class="row">
|
|
||||||
<div class="key">Absolute</div>
|
|
||||||
<div class="value">{{sceneAbsoluteEpisodeNumber}}</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if alternateTitles}}
|
|
||||||
<div class="row">
|
|
||||||
{{#if_gt alternateTitles.length compare="1"}}
|
|
||||||
<div class="key">Titles</div>
|
|
||||||
{{else}}
|
|
||||||
<div class="key">Title</div>
|
|
||||||
{{/if_gt}}
|
|
||||||
<div class="value">
|
|
||||||
<ul>
|
|
||||||
{{#each alternateTitles}}
|
|
||||||
<li>{{title}}</li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
@ -1,21 +0,0 @@
|
|||||||
var NzbDroneCell = require('../../Cells/NzbDroneCell');
|
|
||||||
var SeriesCollection = require('../SeriesCollection');
|
|
||||||
|
|
||||||
module.exports = NzbDroneCell.extend({
|
|
||||||
className : 'episode-warning-cell',
|
|
||||||
|
|
||||||
render : function() {
|
|
||||||
this.$el.empty();
|
|
||||||
|
|
||||||
if (this.model.get('unverifiedSceneNumbering')) {
|
|
||||||
this.$el.html('<i class="icon-sonarr-form-warning" title="Scene number hasn\'t been verified yet."></i>');
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (SeriesCollection.get(this.model.get('seriesId')).get('seriesType') === 'anime' && this.model.get('seasonNumber') > 0 && !this.model.has('absoluteEpisodeNumber')) {
|
|
||||||
this.$el.html('<i class="icon-sonarr-form-warning" title="Episode does not have an absolute episode number"></i>');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.delegateEvents();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
});
|
|
@ -45,7 +45,6 @@ module.exports = Marionette.Layout.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
events : {
|
events : {
|
||||||
'click .x-episode-file-editor' : '_showFiles',
|
|
||||||
'click .x-monitored' : '_toggleMonitored',
|
'click .x-monitored' : '_toggleMonitored',
|
||||||
'click .x-edit' : '_editMovie',
|
'click .x-edit' : '_editMovie',
|
||||||
'click .x-refresh' : '_refreshMovies',
|
'click .x-refresh' : '_refreshMovies',
|
||||||
@ -251,15 +250,6 @@ module.exports = Marionette.Layout.extend({
|
|||||||
this._showInfo();
|
this._showInfo();
|
||||||
},
|
},
|
||||||
|
|
||||||
// _openEpisodeFileEditor : function() {
|
|
||||||
// var view = new EpisodeFileEditorLayout({
|
|
||||||
// movies : this.model,
|
|
||||||
// episodeCollection : this.episodeCollection
|
|
||||||
// });
|
|
||||||
|
|
||||||
// vent.trigger(vent.Commands.OpenModalCommand, view);
|
|
||||||
// },
|
|
||||||
|
|
||||||
_updateImages : function () {
|
_updateImages : function () {
|
||||||
var poster = this._getImage('poster');
|
var poster = this._getImage('poster');
|
||||||
|
|
||||||
|
@ -9,9 +9,6 @@
|
|||||||
{{title}} <span class="year">({{year}}{{#if secondaryYear}} / <a href="https://mappings.radarr.video/mapping/{{secondaryYearSourceId}}" target="_blank"><span title="Secondary year pulled from Radarr Mappings.
|
{{title}} <span class="year">({{year}}{{#if secondaryYear}} / <a href="https://mappings.radarr.video/mapping/{{secondaryYearSourceId}}" target="_blank"><span title="Secondary year pulled from Radarr Mappings.
|
||||||
Click to head on over there and tell us whether this is correct or not.">{{secondaryYear}}</span></a>{{/if}})</span>
|
Click to head on over there and tell us whether this is correct or not.">{{secondaryYear}}</span></a>{{/if}})</span>
|
||||||
<div class="movie-actions pull-right">
|
<div class="movie-actions pull-right">
|
||||||
<div class="x-episode-file-editor">
|
|
||||||
<i class="icon-sonarr-episode-file" title="Modify movie files"/>
|
|
||||||
</div>
|
|
||||||
<div class="x-refresh">
|
<div class="x-refresh">
|
||||||
<i class="icon-sonarr-refresh icon-can-spin" title="Update movie info and scan disk"/>
|
<i class="icon-sonarr-refresh icon-can-spin" title="Update movie info and scan disk"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
var _ = require('underscore');
|
|
||||||
var Marionette = require('marionette');
|
|
||||||
var SeasonLayout = require('./SeasonLayout');
|
|
||||||
var AsSortedCollectionView = require('../../Mixins/AsSortedCollectionView');
|
|
||||||
|
|
||||||
var view = Marionette.CollectionView.extend({
|
|
||||||
|
|
||||||
itemView : SeasonLayout,
|
|
||||||
|
|
||||||
initialize : function(options) {
|
|
||||||
if (!options.episodeCollection) {
|
|
||||||
throw 'episodeCollection is needed';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.episodeCollection = options.episodeCollection;
|
|
||||||
this.series = options.series;
|
|
||||||
},
|
|
||||||
|
|
||||||
itemViewOptions : function() {
|
|
||||||
return {
|
|
||||||
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.get(episode.id);
|
|
||||||
ep.set('downloading', true);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AsSortedCollectionView.call(view);
|
|
||||||
|
|
||||||
module.exports = view;
|
|
@ -1,301 +0,0 @@
|
|||||||
var vent = require('vent');
|
|
||||||
var Marionette = require('marionette');
|
|
||||||
var Backgrid = require('backgrid');
|
|
||||||
var ToggleCell = require('../../Cells/EpisodeMonitoredCell');
|
|
||||||
var EpisodeTitleCell = require('../../Cells/EpisodeTitleCell');
|
|
||||||
var RelativeDateCell = require('../../Cells/RelativeDateCell');
|
|
||||||
var EpisodeStatusCell = require('../../Cells/EpisodeStatusCell');
|
|
||||||
var EpisodeActionsCell = require('../../Cells/EpisodeActionsCell');
|
|
||||||
var EpisodeNumberCell = require('./EpisodeNumberCell');
|
|
||||||
var EpisodeWarningCell = require('./EpisodeWarningCell');
|
|
||||||
var CommandController = require('../../Commands/CommandController');
|
|
||||||
var EpisodeFileEditorLayout = require('../../EpisodeFile/Editor/EpisodeFileEditorLayout');
|
|
||||||
var moment = require('moment');
|
|
||||||
var _ = require('underscore');
|
|
||||||
var Messenger = require('../../Shared/Messenger');
|
|
||||||
|
|
||||||
module.exports = Marionette.Layout.extend({
|
|
||||||
template : 'Movies/Details/SeasonLayoutTemplate',
|
|
||||||
|
|
||||||
ui : {
|
|
||||||
seasonSearch : '.x-season-search',
|
|
||||||
seasonMonitored : '.x-season-monitored',
|
|
||||||
seasonRename : '.x-season-rename'
|
|
||||||
},
|
|
||||||
|
|
||||||
events : {
|
|
||||||
'click .x-season-episode-file-editor' : '_openEpisodeFileEditor',
|
|
||||||
'click .x-season-monitored' : '_seasonMonitored',
|
|
||||||
'click .x-season-search' : '_seasonSearch',
|
|
||||||
'click .x-season-rename' : '_seasonRename',
|
|
||||||
'click .x-show-hide-episodes' : '_showHideEpisodes',
|
|
||||||
'dblclick .series-season h2' : '_showHideEpisodes'
|
|
||||||
},
|
|
||||||
|
|
||||||
regions : {
|
|
||||||
episodeGrid : '.x-episode-grid'
|
|
||||||
},
|
|
||||||
|
|
||||||
columns : [
|
|
||||||
{
|
|
||||||
name : 'monitored',
|
|
||||||
label : '',
|
|
||||||
cell : ToggleCell,
|
|
||||||
trueClass : 'icon-sonarr-monitored',
|
|
||||||
falseClass : 'icon-sonarr-unmonitored',
|
|
||||||
tooltip : 'Toggle monitored status',
|
|
||||||
sortable : false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name : 'episodeNumber',
|
|
||||||
label : '#',
|
|
||||||
cell : EpisodeNumberCell
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name : 'this',
|
|
||||||
label : '',
|
|
||||||
cell : EpisodeWarningCell,
|
|
||||||
sortable : false,
|
|
||||||
className : 'episode-warning-cell'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name : 'this',
|
|
||||||
label : 'Title',
|
|
||||||
hideSeriesLink : true,
|
|
||||||
cell : EpisodeTitleCell,
|
|
||||||
sortable : false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name : 'airDateUtc',
|
|
||||||
label : 'Air Date',
|
|
||||||
cell : RelativeDateCell
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name : 'status',
|
|
||||||
label : 'Status',
|
|
||||||
cell : EpisodeStatusCell,
|
|
||||||
sortable : false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name : 'this',
|
|
||||||
label : '',
|
|
||||||
cell : EpisodeActionsCell,
|
|
||||||
sortable : false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
templateHelpers : function() {
|
|
||||||
var episodeCount = this.episodeCollection.filter(function(episode) {
|
|
||||||
return episode.get('hasFile') || episode.get('monitored') && moment(episode.get('airDateUtc')).isBefore(moment());
|
|
||||||
}).length;
|
|
||||||
|
|
||||||
var episodeFileCount = this.episodeCollection.where({ hasFile : true }).length;
|
|
||||||
var percentOfEpisodes = 100;
|
|
||||||
|
|
||||||
if (episodeCount > 0) {
|
|
||||||
percentOfEpisodes = episodeFileCount / episodeCount * 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
showingEpisodes : this.showingEpisodes,
|
|
||||||
episodeCount : episodeCount,
|
|
||||||
episodeFileCount : episodeFileCount,
|
|
||||||
percentOfEpisodes : percentOfEpisodes
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize : function(options) {
|
|
||||||
if (!options.episodeCollection) {
|
|
||||||
throw 'episodeCollection is required';
|
|
||||||
}
|
|
||||||
|
|
||||||
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._refreshEpisodes);
|
|
||||||
},
|
|
||||||
|
|
||||||
onRender : function() {
|
|
||||||
if (this.showingEpisodes) {
|
|
||||||
this._showEpisodes();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._setSeasonMonitoredState();
|
|
||||||
|
|
||||||
CommandController.bindToCommand({
|
|
||||||
element : this.ui.seasonSearch,
|
|
||||||
command : {
|
|
||||||
name : 'seasonSearch',
|
|
||||||
seriesId : this.series.id,
|
|
||||||
seasonNumber : this.model.get('seasonNumber')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
CommandController.bindToCommand({
|
|
||||||
element : this.ui.seasonRename,
|
|
||||||
command : {
|
|
||||||
name : 'renameFiles',
|
|
||||||
seriesId : this.series.id,
|
|
||||||
seasonNumber : this.model.get('seasonNumber')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_seasonSearch : function() {
|
|
||||||
CommandController.Execute('seasonSearch', {
|
|
||||||
name : 'seasonSearch',
|
|
||||||
seriesId : this.series.id,
|
|
||||||
seasonNumber : this.model.get('seasonNumber')
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_seasonRename : function() {
|
|
||||||
vent.trigger(vent.Commands.ShowRenamePreview, {
|
|
||||||
series : this.series,
|
|
||||||
seasonNumber : this.model.get('seasonNumber')
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_seasonMonitored : function() {
|
|
||||||
if (!this.series.get('monitored')) {
|
|
||||||
|
|
||||||
Messenger.show({
|
|
||||||
message : 'Unable to change monitored state when series is not monitored',
|
|
||||||
type : 'error'
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var name = 'monitored';
|
|
||||||
this.model.set(name, !this.model.get(name));
|
|
||||||
this.series.setSeasonMonitored(this.model.get('seasonNumber'));
|
|
||||||
|
|
||||||
var savePromise = this.series.save().always(this._afterSeasonMonitored.bind(this));
|
|
||||||
|
|
||||||
this.ui.seasonMonitored.spinForPromise(savePromise);
|
|
||||||
},
|
|
||||||
|
|
||||||
_afterSeasonMonitored : function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
_.each(this.episodeCollection.models, function(episode) {
|
|
||||||
episode.set({ monitored : self.model.get('monitored') });
|
|
||||||
});
|
|
||||||
|
|
||||||
this.render();
|
|
||||||
},
|
|
||||||
|
|
||||||
_setSeasonMonitoredState : function() {
|
|
||||||
this.ui.seasonMonitored.removeClass('icon-sonarr-spinner fa-spin');
|
|
||||||
|
|
||||||
if (this.model.get('monitored')) {
|
|
||||||
this.ui.seasonMonitored.addClass('icon-sonarr-monitored');
|
|
||||||
this.ui.seasonMonitored.removeClass('icon-sonarr-unmonitored');
|
|
||||||
} else {
|
|
||||||
this.ui.seasonMonitored.addClass('icon-sonarr-unmonitored');
|
|
||||||
this.ui.seasonMonitored.removeClass('icon-sonarr-monitored');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_showEpisodes : function() {
|
|
||||||
this.episodeGrid.show(new Backgrid.Grid({
|
|
||||||
columns : this.columns,
|
|
||||||
collection : this.episodeCollection,
|
|
||||||
className : 'table table-hover season-grid'
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
_shouldShowEpisodes : function() {
|
|
||||||
var startDate = moment().add(-1, 'month');
|
|
||||||
var endDate = moment().add(1, 'year');
|
|
||||||
|
|
||||||
return this.episodeCollection.some(function(episode) {
|
|
||||||
var airDate = episode.get('airDateUtc');
|
|
||||||
|
|
||||||
if (airDate) {
|
|
||||||
var airDateMoment = moment(airDate);
|
|
||||||
|
|
||||||
if (airDateMoment.isAfter(startDate) && airDateMoment.isBefore(endDate)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_showHideEpisodes : function() {
|
|
||||||
if (this.showingEpisodes) {
|
|
||||||
this.showingEpisodes = false;
|
|
||||||
this.episodeGrid.close();
|
|
||||||
} else {
|
|
||||||
this.showingEpisodes = true;
|
|
||||||
this._showEpisodes();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.templateHelpers.showingEpisodes = this.showingEpisodes;
|
|
||||||
this.render();
|
|
||||||
},
|
|
||||||
|
|
||||||
_episodeMonitoredToggled : function(options) {
|
|
||||||
var model = options.model;
|
|
||||||
var shiftKey = options.shiftKey;
|
|
||||||
|
|
||||||
if (!this.episodeCollection.get(model.get('id'))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shiftKey) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastToggled = this.episodeCollection.lastToggled;
|
|
||||||
|
|
||||||
if (!lastToggled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentIndex = this.episodeCollection.indexOf(model);
|
|
||||||
var lastIndex = this.episodeCollection.indexOf(lastToggled);
|
|
||||||
|
|
||||||
var low = Math.min(currentIndex, lastIndex);
|
|
||||||
var high = Math.max(currentIndex, lastIndex);
|
|
||||||
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;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_refreshEpisodes : function() {
|
|
||||||
this._updateEpisodeCollection();
|
|
||||||
this.episodeCollection.fullCollection.sort();
|
|
||||||
this.render();
|
|
||||||
},
|
|
||||||
|
|
||||||
_openEpisodeFileEditor : function() {
|
|
||||||
var view = new EpisodeFileEditorLayout({
|
|
||||||
model : this.model,
|
|
||||||
series : this.series,
|
|
||||||
episodeCollection : this.episodeCollection
|
|
||||||
});
|
|
||||||
|
|
||||||
vent.trigger(vent.Commands.OpenModalCommand, view);
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,50 +0,0 @@
|
|||||||
<div class="series-season" id="season-{{seasonNumber}}">
|
|
||||||
<h2>
|
|
||||||
<i class="x-season-monitored season-monitored clickable" title="Toggle season monitored status"/>
|
|
||||||
|
|
||||||
{{#if seasonNumber}}
|
|
||||||
Season {{seasonNumber}}
|
|
||||||
{{else}}
|
|
||||||
Specials
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
|
|
||||||
{{#if_eq episodeCount compare=0}}
|
|
||||||
{{#if monitored}}
|
|
||||||
<span class="badge badge-primary season-status" title="No aired episodes"> </span>
|
|
||||||
{{else}}
|
|
||||||
<span class="badge badge-warning season-status" title="Season is not monitored"> </span>
|
|
||||||
{{/if}}
|
|
||||||
{{else}}
|
|
||||||
{{#if_eq percentOfEpisodes compare=100}}
|
|
||||||
<span class="badge badge-success season-status" title="{{episodeFileCount}}/{{episodeCount}} episodes downloaded">{{episodeFileCount}} / {{episodeCount}}</span>
|
|
||||||
{{else}}
|
|
||||||
<span class="badge badge-danger season-status" title="{{episodeFileCount}}/{{episodeCount}} episodes downloaded">{{episodeFileCount}} / {{episodeCount}}</span>
|
|
||||||
{{/if_eq}}
|
|
||||||
{{/if_eq}}
|
|
||||||
|
|
||||||
<span class="season-actions pull-right">
|
|
||||||
<div class="x-season-episode-file-editor">
|
|
||||||
<i class="icon-sonarr-episode-file" title="Modify episode files for season"/>
|
|
||||||
</div>
|
|
||||||
<div class="x-season-rename">
|
|
||||||
<i class="icon-sonarr-rename" title="Preview rename for season {{seasonNumber}}"/>
|
|
||||||
</div>
|
|
||||||
<div class="x-season-search">
|
|
||||||
<i class="icon-sonarr-search" title="Search for monitored episodes in season {{seasonNumber}}"/>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</h2>
|
|
||||||
<div class="show-hide-episodes x-show-hide-episodes">
|
|
||||||
<h4>
|
|
||||||
{{#if showingEpisodes}}
|
|
||||||
<i class="icon-sonarr-panel-hide"/>
|
|
||||||
Hide Episodes
|
|
||||||
{{else}}
|
|
||||||
<i class="icon-sonarr-panel-show"/>
|
|
||||||
Show Episodes
|
|
||||||
{{/if}}
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div class="x-episode-grid table-responsive"></div>
|
|
||||||
</div>
|
|
@ -1,4 +0,0 @@
|
|||||||
<div class="progress episode-progress">
|
|
||||||
<span class="progressbar-back-text">{{episodeFileCount}} / {{episodeCount}}</span>
|
|
||||||
<div class="progress-bar {{EpisodeProgressClass}} episode-progress" style="width:{{percentOfEpisodes}}%"><span class="progressbar-front-text">{{episodeFileCount}} / {{episodeCount}}</span></div>
|
|
||||||
</div>
|
|
@ -222,14 +222,6 @@ var Collection = PageableCollection.extend({
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
percentOfEpisodes : {
|
|
||||||
sortValue : function(model, attr) {
|
|
||||||
var percentOfEpisodes = model.get(attr);
|
|
||||||
var episodeCount = model.get('episodeCount');
|
|
||||||
|
|
||||||
return percentOfEpisodes + episodeCount / 1000000;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
inCinemas : {
|
inCinemas : {
|
||||||
|
|
||||||
sortValue : function(model, attr) {
|
sortValue : function(model, attr) {
|
||||||
|
@ -2,7 +2,6 @@ var Marionette = require('marionette');
|
|||||||
var Backgrid = require('backgrid');
|
var Backgrid = require('backgrid');
|
||||||
var ReleaseCollection = require('./ReleaseCollection');
|
var ReleaseCollection = require('./ReleaseCollection');
|
||||||
var IndexerCell = require('../Cells/IndexerCell');
|
var IndexerCell = require('../Cells/IndexerCell');
|
||||||
var EpisodeNumberCell = require('../Cells/EpisodeNumberCell');
|
|
||||||
var FileSizeCell = require('../Cells/FileSizeCell');
|
var FileSizeCell = require('../Cells/FileSizeCell');
|
||||||
var QualityCell = require('../Cells/QualityCell');
|
var QualityCell = require('../Cells/QualityCell');
|
||||||
var ApprovalStatusCell = require('../Cells/ApprovalStatusCell');
|
var ApprovalStatusCell = require('../Cells/ApprovalStatusCell');
|
||||||
@ -37,12 +36,6 @@ module.exports = Marionette.Layout.extend({
|
|||||||
sortable : true,
|
sortable : true,
|
||||||
cell : ReleaseTitleCell
|
cell : ReleaseTitleCell
|
||||||
},
|
},
|
||||||
/*{
|
|
||||||
name : 'episodeNumbers',
|
|
||||||
episodes : 'episodeNumbers',
|
|
||||||
label : 'season',
|
|
||||||
cell : EpisodeNumberCell
|
|
||||||
},*/
|
|
||||||
{
|
{
|
||||||
name : 'size',
|
name : 'size',
|
||||||
label : 'Size',
|
label : 'Size',
|
||||||
|
@ -92,15 +92,6 @@ var Collection = PageableCollection.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
percentOfEpisodes : {
|
|
||||||
sortValue : function(model, attr) {
|
|
||||||
var percentOfEpisodes = model.get(attr);
|
|
||||||
var episodeCount = model.get('episodeCount');
|
|
||||||
|
|
||||||
return percentOfEpisodes + episodeCount / 1000000;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
path : {
|
path : {
|
||||||
sortValue : function(model) {
|
sortValue : function(model) {
|
||||||
var path = model.get('path');
|
var path = model.get('path');
|
||||||
|
Loading…
Reference in New Issue
Block a user