1
0
Fork 0
mirror of https://github.com/lidarr/Lidarr synced 2024-12-26 01:27:00 +00:00

Added season pass for toggling monitored status of seasons

Linked from missing
This commit is contained in:
Mark McDowall 2013-08-05 02:09:41 -07:00
parent 694714726c
commit 6ca17942f0
12 changed files with 316 additions and 22 deletions

View file

@ -14,13 +14,20 @@ public SeasonModule(ISeasonService seasonService)
GetResourceAll = GetSeasons;
UpdateResource = SetMonitored;
Post["/pass"] = x => SetSeasonPass();
}
private List<SeasonResource> GetSeasons()
{
var seriesId = Request.Query.SeriesId;
return ToListResource<Season>(() => _seasonService.GetSeasonsBySeries(seriesId));
if (seriesId.HasValue)
{
return ToListResource<Season>(() => _seasonService.GetSeasonsBySeries(seriesId));
}
return ToListResource<Season>(() => _seasonService.GetAllSeasons());
}
private SeasonResource SetMonitored(SeasonResource seasonResource)
@ -29,5 +36,13 @@ private SeasonResource SetMonitored(SeasonResource seasonResource)
return seasonResource;
}
private List<SeasonResource> SetSeasonPass()
{
var seriesId = Request.Form.SeriesId;
var seasonNumber = Request.Form.SeasonNumber;
return ToListResource<Season>(() => _seasonService.SetSeasonPass(seriesId, seasonNumber));
}
}
}

Binary file not shown.

View file

@ -16,10 +16,11 @@ define(
'Logs/Files/Layout',
'Release/Layout',
'System/Layout',
'SeasonPass/Layout',
'Shared/NotFoundView',
'Shared/Modal/Region'
], function (App, Marionette, HistoryLayout, SettingsLayout, AddSeriesLayout, SeriesIndexLayout, SeriesDetailsLayout, SeriesCollection, MissingLayout, SeriesModel, CalendarLayout,
LogsLayout, LogFileLayout, ReleaseLayout, SystemLayout, NotFoundView) {
LogsLayout, LogFileLayout, ReleaseLayout, SystemLayout, SeasonPassLayout, NotFoundView) {
return Marionette.Controller.extend({
series: function () {
@ -40,11 +41,6 @@ define(
}
},
_showSeriesDetail: function(seriesModel){
},
addSeries: function (action) {
this._setTitle('Add Series');
App.mainRegion.show(new AddSeriesLayout({action: action}));
@ -55,7 +51,6 @@ define(
App.mainRegion.show(new CalendarLayout());
},
settings: function (action) {
this._setTitle('Settings');
App.mainRegion.show(new SettingsLayout({action: action}));
@ -95,6 +90,11 @@ define(
App.mainRegion.show(new SystemLayout());
},
seasonPass: function () {
this._setTitle('Season Pass');
App.mainRegion.show(new SeasonPassLayout());
},
notFound: function () {
this._setTitle('Not Found');
App.mainRegion.show(new NotFoundView(this));

View file

@ -9,8 +9,9 @@ define(
'Cells/EpisodeTitleCell',
'Cells/RelativeDateCell',
'Shared/Grid/Pager',
'Shared/Toolbar/ToolbarLayout',
'Shared/LoadingView'
], function (Marionette, Backgrid, MissingCollection, SeriesTitleCell, EpisodeNumberCell, EpisodeTitleCell, RelativeDateCell, GridPager, LoadingView) {
], function (Marionette, Backgrid, MissingCollection, SeriesTitleCell, EpisodeNumberCell, EpisodeTitleCell, RelativeDateCell, GridPager, ToolbarLayout, LoadingView) {
return Marionette.Layout.extend({
template: 'Missing/MissingLayoutTemplate',
@ -47,6 +48,19 @@ define(
}
],
leftSideButtons: {
type : 'default',
storeState: false,
items :
[
{
title : 'Season Pass',
icon : 'icon-bookmark',
route : 'seasonpass'
}
]
},
_showTable: function () {
this.missing.show(new Backgrid.Grid({
columns : this.columns,
@ -69,6 +83,18 @@ define(
this.missingCollection.fetch().done(function () {
self._showTable();
});
this._showToolbar();
},
_showToolbar: function () {
this.toolbar.show(new ToolbarLayout({
left :
[
this.leftSideButtons
],
context: this
}));
}
});
});

View file

@ -26,6 +26,7 @@ require(
'logs/:action' : 'logs',
'rss' : 'rss',
'system' : 'system',
'seasonpass' : 'seasonPass',
':whatever' : 'notFound'
}
});

39
UI/SeasonPass/Layout.js Normal file
View file

@ -0,0 +1,39 @@
'use strict';
define(
[
'marionette',
'Series/SeriesCollection',
'Series/SeasonCollection',
'SeasonPass/SeriesCollectionView',
'Shared/LoadingView'
], function (Marionette,
SeriesCollection,
SeasonCollection,
SeriesCollectionView,
LoadingView) {
return Marionette.Layout.extend({
template: 'SeasonPass/LayoutTemplate',
regions: {
series: '#x-series'
},
onShow: function () {
var self = this;
this.series.show(new LoadingView());
this.seriesCollection = SeriesCollection;
this.seasonCollection = new SeasonCollection();
var promise = this.seasonCollection.fetch();
promise.done(function () {
self.series.show(new SeriesCollectionView({
collection: self.seriesCollection,
seasonCollection: self.seasonCollection
}));
});
}
});
});

View file

@ -0,0 +1,11 @@
<div class="row">
<div class="span12">
<div class="alert alert-info">Season Pass allows you to quickly change the monitored status of seasons for all your series in one place</div>
</div>
</div>
<div class="row">
<div class="span12">
<div id="x-series"></div>
</div>
</div>

View file

@ -0,0 +1,26 @@
'use strict';
define(
[
'marionette',
'SeasonPass/SeriesLayout'
], function (Marionette, SeriesLayout) {
return Marionette.CollectionView.extend({
itemView: SeriesLayout,
initialize: function (options) {
if (!options.seasonCollection) {
throw 'seasonCollection is needed';
}
this.seasonCollection = options.seasonCollection;
},
itemViewOptions: function () {
return {
seasonCollection: this.seasonCollection
};
}
});
});

View file

@ -0,0 +1,117 @@
'use strict';
define(
[
'marionette',
'backgrid',
'Series/SeasonCollection',
'Cells/ToggleCell',
'Shared/Actioneer'
], function (Marionette, Backgrid, SeasonCollection, ToggleCell, Actioneer) {
return Marionette.Layout.extend({
template: 'SeasonPass/SeriesLayoutTemplate',
ui: {
seasonSelect: '.x-season-select',
expander : '.x-expander',
seasonGrid : '.x-season-grid'
},
events: {
'change .x-season-select': '_seasonSelected',
'click .x-expander' : '_expand'
},
regions: {
seasonGrid: '.x-season-grid'
},
columns:
[
{
name : 'monitored',
label : '',
cell : ToggleCell,
trueClass : 'icon-bookmark',
falseClass: 'icon-bookmark-empty',
tooltip : 'Toggle monitored status',
sortable : false
},
{
name : 'seasonNumber',
label: 'Season',
cell : Backgrid.IntegerCell.extend({
className: 'season-number-cell'
})
}
],
initialize: function (options) {
this.seasonCollection = options.seasonCollection.bySeries(this.model.get('id'));
this.model.set('seasons', this.seasonCollection);
this.expanded = false;
},
onRender: function () {
this.seasonGrid.show(new Backgrid.Grid({
columns : this.columns,
collection: this.seasonCollection,
className : 'table table-condensed season-grid span5'
}));
if (!this.expanded) {
this.seasonGrid.$el.hide();
}
this._setExpanderIcon();
},
_seasonSelected: function () {
var self = this;
var seasonNumber = parseInt(this.ui.seasonSelect.val());
if (seasonNumber == -1) {
return;
}
var promise = $.ajax({
url: this.seasonCollection.url + '/pass',
type: 'POST',
data: {
seriesId: this.model.get('id'),
seasonNumber: seasonNumber
}
});
promise.done(function (data) {
self.seasonCollection = new SeasonCollection(data);
self.render();
});
},
_expand: function () {
if (this.expanded) {
this.ui.seasonGrid.slideUp();
this.expanded = false;
}
else {
this.ui.seasonGrid.slideDown();
this.expanded = true;
}
this._setExpanderIcon();
},
_setExpanderIcon: function () {
if (this.expanded) {
this.ui.expander.removeClass('icon-chevron-right');
this.ui.expander.addClass('icon-chevron-down');
}
else {
this.ui.expander.removeClass('icon-chevron-down');
this.ui.expander.addClass('icon-chevron-right');
}
}
});
});

View file

@ -0,0 +1,32 @@
<div class="seasonpass-series">
<div class="row">
<div class="span11">
<i class="icon-chevron-right x-expander expander pull-left"/>
<span class="title span5">
<a href="{{route}}">
{{title}}
</a>
</span>
<select class="x-season-select season-select">
<option value="-1">Select season...</option>
{{#each seasons.models}}
{{#if_eq attributes.seasonNumber compare="0"}}
<option value="{{attributes.seasonumber}}">Specials</option>
{{else}}
<option value="{{attributes.seasonNumber}}">Season {{attributes.seasonNumber}}</option>
{{/if_eq}}
{{/each}}
</select>
<span class="help-inline">
<i class="icon-question-sign" title="Selecting a season will unmonitor all previous seasons"/>
</span>
</div>
</div>
<div class="row">
<div class="span11">
<div class="x-season-grid season-grid"></div>
</div>
</div>
</div>

View file

@ -1,24 +1,25 @@
'use strict';
define(
[
'Series/SeasonModel',
'backbone.pageable'
], function (SeasonModel, PageAbleCollection) {
return PageAbleCollection.extend({
'backbone',
'Series/SeasonModel'
], function (Backbone, SeasonModel) {
return Backbone.Collection.extend({
url : window.ApiRoot + '/season',
model: SeasonModel,
mode: 'client',
state: {
sortKey : 'seasonNumber',
order : 1,
pageSize: 1000000
comparator: function (season) {
return -season.get('seasonNumber');
},
queryParams: {
sortKey: null,
order : null
bySeries: function (series) {
var filtered = this.filter(function (season) {
return season.get('seriesId') === series;
});
var SeasonCollection = require('Series/SeasonCollection');
return new SeasonCollection(filtered);
}
});
});

View file

@ -246,4 +246,30 @@
.series-legend {
padding-top: 5px;
}
.seasonpass-series {
.card;
margin : 20px 0px;
.title {
font-weight: 300;
font-size: 24px;
line-height: 30px;
margin-left: 5px;
}
.season-select {
margin-bottom: 0px;
}
.expander {
.clickable;
line-height: 30px;
margin-left: 8px;
}
.season-grid {
margin-top: 10px;
}
}