@ -1,4 +1,4 @@
var vent = require ( 'vent' ) ;
var vent = require ( 'vent' ) ;
var Marionette = require ( 'marionette' ) ;
var Backgrid = require ( 'backgrid' ) ;
var ToggleCell = require ( '../../Cells/EpisodeMonitoredCell' ) ;
@ -14,68 +14,86 @@ var _ = require('underscore');
var Messenger = require ( '../../Shared/Messenger' ) ;
module . exports = Marionette . Layout . extend ( {
template : 'Series/Details/SeasonLayoutTemplate' ,
ui : {
template : 'Series/Details/SeasonLayoutTemplate' ,
ui : {
seasonSearch : '.x-season-search' ,
seasonMonitored : '.x-season-monitored' ,
seasonRename : '.x-season-rename'
} ,
events : {
"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-bookmark' ,
falseClass : 'icon-bookmark-empty' ,
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 ) {
events : {
'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-bookmark' ,
falseClass : 'icon-bookmark-empty' ,
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 episodeFileCount = this . episodeCollection . where ( { hasFile : true } ) . length ;
var percentOfEpisodes = 100 ;
if ( episodeCount > 0 ) {
if ( episodeCount > 0 ) {
percentOfEpisodes = episodeFileCount / episodeCount * 100 ;
}
return {
showingEpisodes : this . showingEpisodes ,
episodeCount : episodeCount ,
@ -83,24 +101,32 @@ module.exports = Marionette.Layout.extend({
percentOfEpisodes : percentOfEpisodes
} ;
} ,
initialize : function ( options ) {
if ( ! options . episodeCollection ) {
initialize : function ( options ) {
if ( ! options . episodeCollection ) {
throw 'episodeCollection is needed' ;
}
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 . _refreshEpsiodes ) ;
} ,
onRender : function ( ) {
if ( this . showingEpisodes ) {
onRender : function ( ) {
if ( this . showingEpisodes ) {
this . _showEpisodes ( ) ;
}
this . _setSeasonMonitoredState ( ) ;
CommandController . bindToCommand ( {
element : this . ui . seasonSearch ,
command : {
@ -109,6 +135,7 @@ module.exports = Marionette.Layout.extend({
seasonNumber : this . model . get ( 'seasonNumber' )
}
} ) ;
CommandController . bindToCommand ( {
element : this . ui . seasonRename ,
command : {
@ -118,112 +145,143 @@ module.exports = Marionette.Layout.extend({
}
} ) ;
} ,
_seasonSearch : function ( ) {
_seasonSearch : function ( ) {
CommandController . Execute ( 'seasonSearch' , {
name : 'seasonSearch' ,
seriesId : this . series . id ,
seasonNumber : this . model . get ( 'seasonNumber' )
} ) ;
} ,
_seasonRename : function ( ) {
_seasonRename : function ( ) {
vent . trigger ( vent . Commands . ShowRenamePreview , {
series : this . series ,
seasonNumber : this . model . get ( 'seasonNumber' )
} ) ;
} ,
_seasonMonitored : function ( ) {
if ( ! this . series . get ( 'monitored' ) ) {
_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 ( ) {
_afterSeasonMonitored : function ( ) {
var self = this ;
_ . each ( this . episodeCollection . models , function ( episode ) {
episode . set ( { monitored : self . model . get ( 'monitored' ) } ) ;
_ . each ( this . episodeCollection . models , function ( episode ) {
episode . set ( { monitored : self . model . get ( 'monitored' ) } ) ;
} ) ;
this . render ( ) ;
} ,
_setSeasonMonitoredState : function ( ) {
_setSeasonMonitoredState : function ( ) {
this . ui . seasonMonitored . removeClass ( 'icon-spinner icon-spin' ) ;
if ( this . model . get ( 'monitored' ) ) {
if ( this . model . get ( 'monitored' ) ) {
this . ui . seasonMonitored . addClass ( 'icon-bookmark' ) ;
this . ui . seasonMonitored . removeClass ( 'icon-bookmark-empty' ) ;
}
else {
} else {
this . ui . seasonMonitored . addClass ( 'icon-bookmark-empty' ) ;
this . ui . seasonMonitored . removeClass ( 'icon-bookmark' ) ;
}
} ,
_showEpisodes : function ( ) {
_showEpisodes : function ( ) {
this . episodeGrid . show ( new Backgrid . Grid ( {
columns : this . columns ,
collection : this . episodeCollection ,
className : 'table table-hover season-grid'
} ) ) ;
} ,
_shouldShowEpisodes : function ( ) {
_shouldShowEpisodes : function ( ) {
var startDate = moment ( ) . add ( 'month' , - 1 ) ;
var endDate = moment ( ) . add ( 'year' , 1 ) ;
return this . episodeCollection . some ( function ( episode ) {
return this . episodeCollection . some ( function ( episode ) {
var airDate = episode . get ( 'airDateUtc' ) ;
if ( airDate ) {
if ( airDate ) {
var airDateMoment = moment ( airDate ) ;
if ( airDateMoment . isAfter ( startDate ) && airDateMoment . isBefore ( endDate ) ) {
if ( airDateMoment . isAfter ( startDate ) && airDateMoment . isBefore ( endDate ) ) {
return true ;
}
}
return false ;
} ) ;
} ,
_showHideEpisodes : function ( ) {
if ( this . showingEpisodes ) {
_showHideEpisodes : function ( ) {
if ( this . showingEpisodes ) {
this . showingEpisodes = false ;
this . episodeGrid . close ( ) ;
}
else {
} else {
this . showingEpisodes = true ;
this . _showEpisodes ( ) ;
}
this . templateHelpers . showingEpisodes = this . showingEpisodes ;
this . render ( ) ;
} ,
_episodeMonitoredToggled : function ( options ) {
_episodeMonitoredToggled : function ( options ) {
var model = options . model ;
var shiftKey = options . shiftKey ;
if ( ! this . episodeCollection . get ( model . get ( 'id' ) ) ) {
if ( ! this . episodeCollection . get ( model . get ( 'id' ) ) ) {
return ;
}
if ( ! shiftKey ) {
if ( ! shiftKey ) {
return ;
}
var lastToggled = this . episodeCollection . lastToggled ;
if ( ! 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 ( ) {
_updateEpisodeCollection : function ( ) {
var self = this ;
this . episodeCollection . add ( this . fullEpisodeCollection . bySeason ( this . model . get ( 'seasonNumber' ) ) . models , { merge : true } ) ;
this . episodeCollection . each ( function ( model ) {
this . episodeCollection . add ( this . fullEpisodeCollection . bySeason ( this . model . get ( 'seasonNumber' ) ) . models , { merge : true } ) ;
this . episodeCollection . each ( function ( model ) {
model . episodeCollection = self . episodeCollection ;
} ) ;
} ,
_refreshEpsiodes : function ( ) {
_refreshEpsiodes : function ( ) {
this . _updateEpisodeCollection ( ) ;
this . render ( ) ;
}