You've already forked Sonarr
							
							
				mirror of
				https://github.com/Sonarr/Sonarr.git
				synced 2025-10-31 00:07:55 +02:00 
			
		
		
		
	rjs -> webpack
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -122,3 +122,4 @@ setup/Output/ | ||||
| #VS outout folders | ||||
| bin | ||||
| obj | ||||
| output/* | ||||
|   | ||||
| @@ -221,15 +221,12 @@ Function PackageTests() | ||||
| Function RunGulp() | ||||
| { | ||||
|    Write-Host "##teamcity[progressStart 'Running Gulp']" | ||||
|    $gulpPath = '.\node_modules\gulp\bin\gulp' | ||||
|    Invoke-Expression  'npm install' | ||||
|    CheckExitCode | ||||
|  | ||||
|    Invoke-Expression  ('node ' + $gulpPath + ' build') -ErrorAction Continue -Verbose | ||||
|    Invoke-Expression 'gulp build' -ErrorAction Continue -Verbose | ||||
|    CheckExitCode | ||||
|  | ||||
|    Remove-Item $outputFolder\UI\build.txt -ErrorAction Continue | ||||
|  | ||||
|    Write-Host "##teamcity[progressFinish 'Running Gulp']" | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										50
									
								
								commonjsCleanup.linq
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								commonjsCleanup.linq
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| <Query Kind="Program" /> | ||||
|  | ||||
| void Main() | ||||
| { | ||||
| 	var files = Directory.GetFiles("c:\\git\\sonarr\\src\\UI","*.js", SearchOption.AllDirectories); | ||||
| 	 | ||||
| 	var moduleRegex = new Regex(@"module.exports\s*=\s*\(function\s*\(\)\s*{\n\s*return\s*(\w|\W)*\)\.call\(this\);$"); | ||||
| 	var functionHead = new Regex(@"\s*\(function\s*\(\)\s*{\n\s*return\s*"); | ||||
| 	var functionTail = new Regex(@"\}\).call\(this\);$"); | ||||
|     var multiVar = new Regex(@"^(?<d>var\s*\w*\s*=\s*require\(.*\)),"); | ||||
| 	var seperateDeclearatuin = new Regex(@"^((\w|\$|_)*\s=\srequire\(.*\))(,|;)", RegexOptions.Multiline); | ||||
| 	 | ||||
| 	foreach (var filePath in files) | ||||
| 	{ | ||||
| 	 	var text = File.ReadAllText(filePath); | ||||
| 		 | ||||
| 		var newContent = text.Replace("// Generated by uRequire v0.7.0-beta.14  template: 'nodejs'",""); | ||||
| 		 | ||||
| 		newContent = newContent.Replace("var __isAMD = !!(typeof define === 'function' && define.amd),",""); | ||||
| 	    newContent = newContent.Replace("__isNode = (typeof exports === 'object'),",""); | ||||
| 		newContent = newContent.Replace("__isWeb = !__isNode;",""); | ||||
| 		newContent = newContent.Replace("\"use strict\";","'use strict';"); | ||||
| 		 | ||||
| 		newContent = newContent.Trim(); | ||||
| 		 | ||||
|  | ||||
| 		 | ||||
| 		if(moduleRegex.IsMatch(newContent)) | ||||
| 		{ | ||||
| 			filePath.Dump(); | ||||
| 			 | ||||
| 			newContent = functionHead.Replace(newContent," "); | ||||
| 			newContent = functionTail.Replace(newContent,""); | ||||
| 		} | ||||
| 		 | ||||
| 		if(multiVar.IsMatch(newContent)) | ||||
| 		{ | ||||
| 			newContent = multiVar.Replace(newContent,"$1;"); //first one | ||||
| 		 | ||||
| 		} | ||||
| 		 | ||||
| 		newContent = seperateDeclearatuin.Replace(newContent,"var $1;"); //ones after | ||||
| 		newContent.Replace("var $ = require('jquery'), var","var $ = require('jquery');"); | ||||
| 		 | ||||
| 		File.WriteAllText(filePath,newContent.Trim()); | ||||
| 		 | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Define other methods and classes here | ||||
| @@ -2,12 +2,11 @@ var gulp = require('gulp'); | ||||
| var runSequence = require('run-sequence'); | ||||
|  | ||||
| require('./clean'); | ||||
| require('./requirejs'); | ||||
| require('./less'); | ||||
| require('./handlebars'); | ||||
| require('./copy'); | ||||
|  | ||||
| gulp.task('build', function () { | ||||
|     return  runSequence('clean', | ||||
|         ['requireJs', 'less', 'handlebars', 'copyHtml', 'copyContent']); | ||||
|         ['webpack', 'less', 'handlebars', 'copyHtml', 'copyContent', 'copyJs']); | ||||
| }); | ||||
|   | ||||
| @@ -5,7 +5,12 @@ var cache = require('gulp-cached'); | ||||
| var paths = require('./paths.js'); | ||||
|  | ||||
| gulp.task('copyJs', function () { | ||||
|     return gulp.src(paths.src.scripts) | ||||
|     return gulp.src( | ||||
|       [ | ||||
|         paths.src.root + "piwikCheck.js", | ||||
|         paths.src.root + "polyfills.js", | ||||
|         paths.src.root + "JsLibraries\\handlebars.runtime.js", | ||||
|       ]) | ||||
|         .pipe(cache('copyJs')) | ||||
|         .pipe(print()) | ||||
|         .pipe(gulp.dest(paths.dest.root)); | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| require('./watch.js'); | ||||
| require('./build.js'); | ||||
| require('./clean.js'); | ||||
| require('./requirejs.js'); | ||||
| require('./jshint.js'); | ||||
| require('./handlebars.js'); | ||||
| require('./copy.js'); | ||||
| require('./less.js'); | ||||
| require('./stripBom.js'); | ||||
| require('./imageMin.js'); | ||||
| require('./webpack.js'); | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,6 @@ var gulp = require('gulp'); | ||||
| var handlebars = require('gulp-handlebars'); | ||||
| var declare = require('gulp-declare'); | ||||
| var concat = require('gulp-concat'); | ||||
| var wrapAmd = require('gulp-wrap-amd'); | ||||
| var wrap = require("gulp-wrap"); | ||||
| var path = require('path'); | ||||
| var streamqueue = require('streamqueue'); | ||||
| @@ -48,10 +47,6 @@ gulp.task('handlebars', function () { | ||||
|         partialStream, | ||||
|         coreStream | ||||
|     ).pipe(concat('templates.js')) | ||||
|         .pipe(wrapAmd({ | ||||
|             deps: ['handlebars'], | ||||
|             params: ['Handlebars'], | ||||
|             exports: 'this["T"]' | ||||
|         })) | ||||
|  | ||||
|         .pipe(gulp.dest(paths.dest.root)); | ||||
| }); | ||||
|   | ||||
| @@ -15,6 +15,7 @@ gulp.task('jshint', function () { | ||||
|             '-W100': false, //Silently deleted characters (in locales) | ||||
|             'undef': true, | ||||
|             'globals': { | ||||
|                 'module': true, | ||||
|                 'require': true, | ||||
|                 'define': true, | ||||
|                 'window': true, | ||||
|   | ||||
| @@ -1,32 +0,0 @@ | ||||
| var gulp = require('gulp'); | ||||
| var requirejs = require('requirejs'); | ||||
| var paths = require('./paths'); | ||||
|  | ||||
| require('./handlebars.js'); | ||||
| require('./jshint.js'); | ||||
|  | ||||
|  | ||||
| gulp.task('requireJs', ['jshint'], function (cb) { | ||||
|  | ||||
|     var config = { | ||||
|         mainConfigFile: 'src/UI/app.js', | ||||
|         fileExclusionRegExp: /^.*\.(?!js$)[^.]+$/, | ||||
|         preserveLicenseComments: false, | ||||
|         dir: paths.dest.root, | ||||
|         optimize: 'none', | ||||
|         removeCombined: true, | ||||
|         inlineText: false, | ||||
|         keepBuildDir: true, | ||||
|         modules: [ | ||||
|             { | ||||
|                 name: 'app', | ||||
|                 exclude: ['templates.js'] | ||||
|             } | ||||
|         ]}; | ||||
|  | ||||
|     requirejs.optimize(config, function (buildResponse) { | ||||
|         console.log(buildResponse); | ||||
|         cb(); | ||||
|     }); | ||||
|  | ||||
| }); | ||||
| @@ -8,17 +8,19 @@ require('./jshint.js'); | ||||
| require('./handlebars.js'); | ||||
| require('./less.js'); | ||||
| require('./copy.js'); | ||||
| require('./webpack.js'); | ||||
|  | ||||
|  | ||||
| gulp.task('watch', ['jshint', 'handlebars', 'less', 'copyJs', 'copyHtml', 'copyContent'], function () { | ||||
|     gulp.watch([paths.src.scripts, paths.src.exclude.libs], ['jshint', 'copyJs']); | ||||
| gulp.task('watch', ['jshint', 'handlebars', 'less','copyHtml', 'copyContent','copyJs'], function () { | ||||
|     gulp.start('webpackWatch'); | ||||
|     gulp.watch([paths.src.scripts, paths.src.exclude.libs], ['jshint','copyJs']); | ||||
|     gulp.watch(paths.src.templates, ['handlebars']); | ||||
|     gulp.watch([paths.src.less, paths.src.exclude.libs], ['less']); | ||||
|     gulp.watch([paths.src.html], ['copyHtml']); | ||||
|     gulp.watch([paths.src.content + '**/*.*', '!**/*.less'], ['copyContent']); | ||||
| }); | ||||
|  | ||||
| gulp.task('liveReload', ['jshint', 'handlebars', 'less', 'copyJs'], function () { | ||||
| gulp.task('liveReload', ['jshint', 'handlebars', 'less', 'webPack'], function () { | ||||
|     var server = livereload(); | ||||
|     gulp.watch([ | ||||
|         'app/**/*.js', | ||||
|   | ||||
							
								
								
									
										20
									
								
								gulp/webpack.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								gulp/webpack.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| var gulp = require('gulp'); | ||||
|  | ||||
| var gulpWebpack = require('gulp-webpack'); | ||||
| var webpack = require('webpack'); | ||||
| var webpackConfig = require('../webpack.config'); | ||||
|  | ||||
| webpackConfig.devtool = "#source-map"; | ||||
|  | ||||
| gulp.task('webpack', function() { | ||||
|   return gulp.src('main.js') | ||||
|     .pipe(gulpWebpack(webpackConfig, webpack)) | ||||
|     .pipe(gulp.dest('')); | ||||
| }); | ||||
|  | ||||
| gulp.task('webpackWatch', function() { | ||||
|   webpackConfig.watch = true; | ||||
|   return gulp.src('main.js') | ||||
|     .pipe(gulpWebpack(webpackConfig, webpack)) | ||||
|     .pipe(gulp.dest('')); | ||||
| }); | ||||
							
								
								
									
										11
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,8 +1,8 @@ | ||||
| { | ||||
|   "name": "Sonarr", | ||||
|   "version": "0.0.0", | ||||
|   "version": "2.0.0", | ||||
|   "description": "Sonarr", | ||||
|   "main": "index.js", | ||||
|   "main": "main.js", | ||||
|   "scripts": { | ||||
|     "preinstall": "" | ||||
|   }, | ||||
| @@ -15,10 +15,10 @@ | ||||
|   "gitHead": "9ff7aa1bf7fe38c4c5bdb92f56c8ad556916ed67", | ||||
|   "readmeFilename": "readme.md", | ||||
|   "dependencies": { | ||||
|     "del": "0.1.3", | ||||
|     "fs-extra": "0.12.0", | ||||
|     "gulp": "3.8.10", | ||||
|     "gulp-cached": "1.0.1", | ||||
|     "del": "0.1.3", | ||||
|     "gulp-concat": "2.4.2", | ||||
|     "gulp-declare": "0.3.0", | ||||
|     "gulp-handlebars": "2.2.0", | ||||
| @@ -26,10 +26,11 @@ | ||||
|     "gulp-less": "1.3.6", | ||||
|     "gulp-print": "1.1.0", | ||||
|     "gulp-replace": "0.5.0", | ||||
|     "gulp-run": "1.6.6", | ||||
|     "webpack": "1.4.15", | ||||
|     "gulp-webpack": "1.2.0", | ||||
|     "gulp-wrap": "0.5.0", | ||||
|     "gulp-wrap-amd": "0.3.1", | ||||
|     "jshint-stylish": "1.0.0", | ||||
|     "requirejs": "2.1.15", | ||||
|     "run-sequence": "1.0.2", | ||||
|     "streamqueue": "0.1.1" | ||||
|   } | ||||
|   | ||||
| @@ -27,6 +27,7 @@ namespace NzbDrone.Api.Frontend.Mappers | ||||
|         { | ||||
|             return resourceUrl.StartsWith("/Content") || | ||||
|                    resourceUrl.EndsWith(".js") || | ||||
|                    resourceUrl.EndsWith(".map") || | ||||
|                    resourceUrl.EndsWith(".css") || | ||||
|                    (resourceUrl.EndsWith(".ico") && !resourceUrl.Equals("/favicon.ico")) || | ||||
|                    resourceUrl.EndsWith(".swf"); | ||||
|   | ||||
							
								
								
									
										13
									
								
								src/UI/.idea/codeStyleSettings.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										13
									
								
								src/UI/.idea/codeStyleSettings.xml
									
									
									
										generated
									
									
									
								
							| @@ -19,6 +19,8 @@ | ||||
|         <JSCodeStyleSettings> | ||||
|           <option name="SPACE_BEFORE_PROPERTY_COLON" value="true" /> | ||||
|           <option name="ALIGN_OBJECT_PROPERTIES" value="2" /> | ||||
|           <option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" /> | ||||
|           <option name="OBJECT_LITERAL_WRAP" value="2" /> | ||||
|         </JSCodeStyleSettings> | ||||
|         <XML> | ||||
|           <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" /> | ||||
| @@ -29,14 +31,18 @@ | ||||
|           </indentOptions> | ||||
|         </codeStyleSettings> | ||||
|         <codeStyleSettings language="JavaScript"> | ||||
|           <option name="LINE_COMMENT_AT_FIRST_COLUMN" value="true" /> | ||||
|           <option name="KEEP_LINE_BREAKS" value="false" /> | ||||
|           <option name="KEEP_FIRST_COLUMN_COMMENT" value="false" /> | ||||
|           <option name="ELSE_ON_NEW_LINE" value="true" /> | ||||
|           <option name="CATCH_ON_NEW_LINE" value="true" /> | ||||
|           <option name="FINALLY_ON_NEW_LINE" value="true" /> | ||||
|           <option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> | ||||
|           <option name="SPACE_BEFORE_METHOD_PARENTHESES" value="true" /> | ||||
|           <option name="METHOD_PARAMETERS_WRAP" value="5" /> | ||||
|           <option name="ARRAY_INITIALIZER_WRAP" value="2" /> | ||||
|           <option name="SPACE_BEFORE_IF_PARENTHESES" value="false" /> | ||||
|           <option name="SPACE_BEFORE_METHOD_LBRACE" value="false" /> | ||||
|           <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" /> | ||||
|           <option name="ARRAY_INITIALIZER_WRAP" value="1" /> | ||||
|           <option name="IF_BRACE_FORCE" value="3" /> | ||||
|           <option name="DOWHILE_BRACE_FORCE" value="3" /> | ||||
|           <option name="WHILE_BRACE_FORCE" value="3" /> | ||||
| @@ -46,5 +52,4 @@ | ||||
|     </option> | ||||
|     <option name="USE_PER_PROJECT_SETTINGS" value="true" /> | ||||
|   </component> | ||||
| </project> | ||||
|  | ||||
| </project> | ||||
							
								
								
									
										7
									
								
								src/UI/.idea/encodings.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								src/UI/.idea/encodings.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,5 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project version="4"> | ||||
|   <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" /> | ||||
| </project> | ||||
|  | ||||
|   <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false"> | ||||
|     <file url="file://$PROJECT_DIR$/System/Logs/Files/LogFileModel.js" charset="UTF-8" /> | ||||
|   </component> | ||||
| </project> | ||||
							
								
								
									
										38
									
								
								src/UI/.idea/jsLinters/jshint.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										38
									
								
								src/UI/.idea/jsLinters/jshint.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project version="4"> | ||||
|   <component name="JSHintConfiguration" version="2.1.10" use-config-file="false"> | ||||
|   <component name="JSHintConfiguration" version="2.6.0" use-config-file="false"> | ||||
|     <option bitwise="true" /> | ||||
|     <option camelcase="true" /> | ||||
|     <option curly="true" /> | ||||
| @@ -14,7 +14,7 @@ | ||||
|     <option nonew="true" /> | ||||
|     <option plusplus="false" /> | ||||
|     <option undef="true" /> | ||||
|     <option strict="true" /> | ||||
|     <option strict="false" /> | ||||
|     <option trailing="false" /> | ||||
|     <option latedef="true" /> | ||||
|     <option unused="true" /> | ||||
| @@ -27,40 +27,46 @@ | ||||
|     <option esnext="false" /> | ||||
|     <option evil="false" /> | ||||
|     <option expr="false" /> | ||||
|     <option funcscope="false" /> | ||||
|     <option globalstrict="true" /> | ||||
|     <option iterator="false" /> | ||||
|     <option lastsemic="false" /> | ||||
|     <option laxbreak="false" /> | ||||
|     <option laxcomma="false" /> | ||||
|     <option loopfunc="false" /> | ||||
|     <option multistr="false" /> | ||||
|     <option notypeof="false" /> | ||||
|     <option proto="false" /> | ||||
|     <option scripturl="false" /> | ||||
|     <option smarttabs="false" /> | ||||
|     <option shadow="false" /> | ||||
|     <option sub="false" /> | ||||
|     <option supernew="false" /> | ||||
|     <option validthis="false" /> | ||||
|     <option browser="true" /> | ||||
|     <option couch="false" /> | ||||
|     <option devel="true" /> | ||||
|     <option dojo="false" /> | ||||
|     <option freeze="false" /> | ||||
|     <option funcscope="false" /> | ||||
|     <option gcl="false" /> | ||||
|     <option iterator="false" /> | ||||
|     <option loopfunc="false" /> | ||||
|     <option shadow="false" /> | ||||
|     <option jquery="false" /> | ||||
|     <option mootools="false" /> | ||||
|     <option node="false" /> | ||||
|     <option nonstandard="false" /> | ||||
|     <option nomen="false" /> | ||||
|     <option maxerr="50" /> | ||||
|     <option moz="false" /> | ||||
|     <option noyield="false" /> | ||||
|     <option phantom="false" /> | ||||
|     <option smarttabs="false" /> | ||||
|     <option supernew="false" /> | ||||
|     <option validthis="false" /> | ||||
|     <option mootools="false" /> | ||||
|     <option node="true" /> | ||||
|     <option nonbsp="false" /> | ||||
|     <option prototypejs="false" /> | ||||
|     <option rhino="false" /> | ||||
|     <option worker="false" /> | ||||
|     <option wsh="false" /> | ||||
|     <option yui="false" /> | ||||
|     <option nomen="false" /> | ||||
|     <option onevar="false" /> | ||||
|     <option passfail="false" /> | ||||
|     <option white="false" /> | ||||
|     <option maxerr="50" /> | ||||
|     <option predef="window, define, require" /> | ||||
|     <option predef="window, define, require, module" /> | ||||
|   </component> | ||||
| </project> | ||||
|  | ||||
| </project> | ||||
| @@ -1,85 +1,72 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'backbone', | ||||
|         'backgrid', | ||||
|         'Activity/History/HistoryLayout', | ||||
|         'Activity/Blacklist/BlacklistLayout', | ||||
|         'Activity/Queue/QueueLayout' | ||||
|     ], function (Marionette, Backbone, Backgrid, HistoryLayout, BlacklistLayout, QueueLayout) { | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'Activity/ActivityLayoutTemplate', | ||||
| var Marionette = require('marionette'); | ||||
| var Backbone = require('backbone'); | ||||
| var Backgrid = require('backgrid'); | ||||
| var HistoryLayout = require('./History/HistoryLayout'); | ||||
| var BlacklistLayout = require('./Blacklist/BlacklistLayout'); | ||||
| var QueueLayout = require('./Queue/QueueLayout'); | ||||
|  | ||||
|             regions: { | ||||
|                 queueRegion : '#queue', | ||||
|                 history     : '#history', | ||||
|                 blacklist   : '#blacklist' | ||||
|             }, | ||||
|  | ||||
|             ui: { | ||||
|                 queueTab     : '.x-queue-tab', | ||||
|                 historyTab   : '.x-history-tab', | ||||
|                 blacklistTab : '.x-blacklist-tab' | ||||
|             }, | ||||
|  | ||||
|             events: { | ||||
|                 'click .x-queue-tab'     : '_showQueue', | ||||
|                 'click .x-history-tab'   : '_showHistory', | ||||
|                 'click .x-blacklist-tab' : '_showBlacklist' | ||||
|             }, | ||||
|  | ||||
|             initialize: function (options) { | ||||
|                 if (options.action) { | ||||
|                     this.action = options.action.toLowerCase(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 switch (this.action) { | ||||
|                     case 'history': | ||||
|                         this._showHistory(); | ||||
|                         break; | ||||
|                     case 'blacklist': | ||||
|                         this._showBlacklist(); | ||||
|                         break; | ||||
|                     default: | ||||
|                         this._showQueue(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             _navigate: function (route) { | ||||
|                 Backbone.history.navigate(route, { trigger: false, replace: true }); | ||||
|             }, | ||||
|  | ||||
|             _showHistory: function (e) { | ||||
|                 if (e) { | ||||
|                     e.preventDefault(); | ||||
|                 } | ||||
|  | ||||
|                 this.history.show(new HistoryLayout()); | ||||
|                 this.ui.historyTab.tab('show'); | ||||
|                 this._navigate('/activity/history'); | ||||
|             }, | ||||
|  | ||||
|             _showBlacklist: function (e) { | ||||
|                 if (e) { | ||||
|                     e.preventDefault(); | ||||
|                 } | ||||
|  | ||||
|                 this.blacklist.show(new BlacklistLayout()); | ||||
|                 this.ui.blacklistTab.tab('show'); | ||||
|                 this._navigate('/activity/blacklist'); | ||||
|             }, | ||||
|  | ||||
|             _showQueue: function (e) { | ||||
|                 if (e) { | ||||
|                     e.preventDefault(); | ||||
|                 } | ||||
|  | ||||
|                 this.queueRegion.show(new QueueLayout()); | ||||
|                 this.ui.queueTab.tab('show'); | ||||
|                 this._navigate('/activity/queue'); | ||||
|             } | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template       : 'Activity/ActivityLayoutTemplate', | ||||
|     regions        : { | ||||
|         queueRegion : '#queue', | ||||
|         history     : '#history', | ||||
|         blacklist   : '#blacklist' | ||||
|     }, | ||||
|     ui             : { | ||||
|         queueTab     : '.x-queue-tab', | ||||
|         historyTab   : '.x-history-tab', | ||||
|         blacklistTab : '.x-blacklist-tab' | ||||
|     }, | ||||
|     events         : { | ||||
|         "click .x-queue-tab"     : '_showQueue', | ||||
|         "click .x-history-tab"   : '_showHistory', | ||||
|         "click .x-blacklist-tab" : '_showBlacklist' | ||||
|     }, | ||||
|     initialize     : function(options){ | ||||
|         if(options.action) { | ||||
|             this.action = options.action.toLowerCase(); | ||||
|         } | ||||
|     }, | ||||
|     onShow         : function(){ | ||||
|         switch (this.action) { | ||||
|             case 'history': | ||||
|                 this._showHistory(); | ||||
|                 break; | ||||
|             case 'blacklist': | ||||
|                 this._showBlacklist(); | ||||
|                 break; | ||||
|             default: | ||||
|                 this._showQueue(); | ||||
|         } | ||||
|     }, | ||||
|     _navigate      : function(route){ | ||||
|         Backbone.history.navigate(route, { | ||||
|             trigger : false, | ||||
|             replace : true | ||||
|         }); | ||||
|     }); | ||||
|     }, | ||||
|     _showHistory   : function(e){ | ||||
|         if(e) { | ||||
|             e.preventDefault(); | ||||
|         } | ||||
|         this.history.show(new HistoryLayout()); | ||||
|         this.ui.historyTab.tab('show'); | ||||
|         this._navigate('/activity/history'); | ||||
|     }, | ||||
|     _showBlacklist : function(e){ | ||||
|         if(e) { | ||||
|             e.preventDefault(); | ||||
|         } | ||||
|         this.blacklist.show(new BlacklistLayout()); | ||||
|         this.ui.blacklistTab.tab('show'); | ||||
|         this._navigate('/activity/blacklist'); | ||||
|     }, | ||||
|     _showQueue     : function(e){ | ||||
|         if(e) { | ||||
|             e.preventDefault(); | ||||
|         } | ||||
|         this.queueRegion.show(new QueueLayout()); | ||||
|         this.ui.queueTab.tab('show'); | ||||
|         this._navigate('/activity/queue'); | ||||
|     } | ||||
| }); | ||||
| @@ -1,26 +1,16 @@ | ||||
| 'use strict'; | ||||
| var NzbDroneCell = require('../../Cells/NzbDroneCell'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function (NzbDroneCell) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className: 'blacklist-controls-cell', | ||||
|  | ||||
|             events: { | ||||
|                 'click': '_delete' | ||||
|             }, | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|                 this.$el.html('<i class="icon-nd-delete"></i>'); | ||||
|  | ||||
|                 return this; | ||||
|             }, | ||||
|  | ||||
|             _delete: function () { | ||||
|                 this.model.destroy(); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className : 'blacklist-controls-cell', | ||||
|     events    : { | ||||
|         'click' : '_delete' | ||||
|     }, | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         this.$el.html('<i class="icon-nd-delete"></i>'); | ||||
|         return this; | ||||
|     }, | ||||
|     _delete   : function(){ | ||||
|         this.model.destroy(); | ||||
|     } | ||||
| }); | ||||
| @@ -1,50 +1,39 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'Activity/Blacklist/BlacklistModel', | ||||
|         'backbone.pageable', | ||||
|         'Mixins/AsSortedCollection', | ||||
|         'Mixins/AsPersistedStateCollection' | ||||
|     ], function (BlacklistModel, PageableCollection, AsSortedCollection, AsPersistedStateCollection) { | ||||
|         var Collection = PageableCollection.extend({ | ||||
|             url  : window.NzbDrone.ApiRoot + '/blacklist', | ||||
|             model: BlacklistModel, | ||||
| var BlacklistModel = require('./BlacklistModel'); | ||||
| var PageableCollection = require('backbone.pageable'); | ||||
| var AsSortedCollection = require('../../Mixins/AsSortedCollection'); | ||||
| var AsPersistedStateCollection = require('../../Mixins/AsPersistedStateCollection'); | ||||
|  | ||||
|             state: { | ||||
|                 pageSize: 15, | ||||
|                 sortKey : 'date', | ||||
|                 order   : 1 | ||||
|             }, | ||||
|  | ||||
|             queryParams: { | ||||
|                 totalPages  : null, | ||||
|                 totalRecords: null, | ||||
|                 pageSize    : 'pageSize', | ||||
|                 sortKey     : 'sortKey', | ||||
|                 order       : 'sortDir', | ||||
|                 directions  : { | ||||
|                     '-1': 'asc', | ||||
|                     '1' : 'desc' | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             sortMappings: { | ||||
|                 'series'   : { sortKey: 'series.sortTitle' } | ||||
|             }, | ||||
|  | ||||
|             parseState: function (resp) { | ||||
|                 return { totalRecords: resp.totalRecords }; | ||||
|             }, | ||||
|  | ||||
|             parseRecords: function (resp) { | ||||
|                 if (resp) { | ||||
|                     return resp.records; | ||||
|                 } | ||||
|  | ||||
|                 return resp; | ||||
| module.exports = (function(){ | ||||
|     var Collection = PageableCollection.extend({ | ||||
|         url          : window.NzbDrone.ApiRoot + '/blacklist', | ||||
|         model        : BlacklistModel, | ||||
|         state        : { | ||||
|             pageSize : 15, | ||||
|             sortKey  : 'date', | ||||
|             order    : 1 | ||||
|         }, | ||||
|         queryParams  : { | ||||
|             totalPages   : null, | ||||
|             totalRecords : null, | ||||
|             pageSize     : 'pageSize', | ||||
|             sortKey      : 'sortKey', | ||||
|             order        : 'sortDir', | ||||
|             directions   : { | ||||
|                 '-1' : 'asc', | ||||
|                 '1'  : 'desc' | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         Collection = AsSortedCollection.call(Collection); | ||||
|         return AsPersistedStateCollection.call(Collection); | ||||
|         }, | ||||
|         sortMappings : {'series' : {sortKey : 'series.sortTitle'}}, | ||||
|         parseState   : function(resp){ | ||||
|             return {totalRecords : resp.totalRecords}; | ||||
|         }, | ||||
|         parseRecords : function(resp){ | ||||
|             if(resp) { | ||||
|                 return resp.records; | ||||
|             } | ||||
|             return resp; | ||||
|         } | ||||
|     }); | ||||
|     Collection = AsSortedCollection.call(Collection); | ||||
|     return AsPersistedStateCollection.call(Collection); | ||||
| }).call(this); | ||||
| @@ -1,131 +1,91 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'vent', | ||||
|         'marionette', | ||||
|         'backgrid', | ||||
|         'Activity/Blacklist/BlacklistCollection', | ||||
|         'Cells/SeriesTitleCell', | ||||
|         'Cells/QualityCell', | ||||
|         'Cells/RelativeDateCell', | ||||
|         'Activity/Blacklist/BlacklistActionsCell', | ||||
|         'Shared/Grid/Pager', | ||||
|         'Shared/LoadingView', | ||||
|         'Shared/Toolbar/ToolbarLayout' | ||||
|     ], function (vent, | ||||
|                  Marionette, | ||||
|                  Backgrid, | ||||
|                  BlacklistCollection, | ||||
|                  SeriesTitleCell, | ||||
|                  QualityCell, | ||||
|                  RelativeDateCell, | ||||
|                  BlacklistActionsCell, | ||||
|                  GridPager, | ||||
|                  LoadingView, | ||||
|                  ToolbarLayout) { | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'Activity/Blacklist/BlacklistLayoutTemplate', | ||||
| var vent = require('../../vent'); | ||||
| var Marionette = require('marionette'); | ||||
| var Backgrid = require('backgrid'); | ||||
| var BlacklistCollection = require('./BlacklistCollection'); | ||||
| var SeriesTitleCell = require('../../Cells/SeriesTitleCell'); | ||||
| var QualityCell = require('../../Cells/QualityCell'); | ||||
| var RelativeDateCell = require('../../Cells/RelativeDateCell'); | ||||
| var BlacklistActionsCell = require('./BlacklistActionsCell'); | ||||
| var GridPager = require('../../Shared/Grid/Pager'); | ||||
| var LoadingView = require('../../Shared/LoadingView'); | ||||
| var ToolbarLayout = require('../../Shared/Toolbar/ToolbarLayout'); | ||||
|  | ||||
|             regions: { | ||||
|                 blacklist : '#x-blacklist', | ||||
|                 toolbar   : '#x-toolbar', | ||||
|                 pager     : '#x-pager' | ||||
|             }, | ||||
|  | ||||
|             columns: | ||||
|                 [ | ||||
|                     { | ||||
|                         name      : 'series', | ||||
|                         label     : 'Series', | ||||
|                         cell      : SeriesTitleCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name      : 'sourceTitle', | ||||
|                         label     : 'Source Title', | ||||
|                         cell      : 'string' | ||||
|                     }, | ||||
|                     { | ||||
|                         name      : 'quality', | ||||
|                         label     : 'Quality', | ||||
|                         cell      : QualityCell, | ||||
|                         sortable  : false | ||||
|                     }, | ||||
|                     { | ||||
|                         name      : 'date', | ||||
|                         label     : 'Date', | ||||
|                         cell      : RelativeDateCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name      : 'this', | ||||
|                         label     : '', | ||||
|                         cell      : BlacklistActionsCell, | ||||
|                         sortable  : false | ||||
|                     } | ||||
|                 ], | ||||
|  | ||||
|             initialize: function () { | ||||
|                 this.collection = new BlacklistCollection({ tableName: 'blacklist' }); | ||||
|  | ||||
|                 this.listenTo(this.collection, 'sync', this._showTable); | ||||
|                 this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete); | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 this.blacklist.show(new LoadingView()); | ||||
|                 this._showToolbar(); | ||||
|                 this.collection.fetch(); | ||||
|             }, | ||||
|  | ||||
|             _showTable: function (collection) { | ||||
|  | ||||
|                 this.blacklist.show(new Backgrid.Grid({ | ||||
|                     columns   : this.columns, | ||||
|                     collection: collection, | ||||
|                     className : 'table table-hover' | ||||
|                 })); | ||||
|  | ||||
|                 this.pager.show(new GridPager({ | ||||
|                     columns   : this.columns, | ||||
|                     collection: collection | ||||
|                 })); | ||||
|             }, | ||||
|  | ||||
|             _showToolbar: function () { | ||||
|                 var leftSideButtons = { | ||||
|                     type      : 'default', | ||||
|                         storeState: false, | ||||
|                         items     : | ||||
|                     [ | ||||
|                         { | ||||
|                             title          : 'Clear Blacklist', | ||||
|                             icon           : 'icon-trash', | ||||
|                             command        : 'clearBlacklist' | ||||
|                         } | ||||
|                     ] | ||||
|                 }; | ||||
|  | ||||
|                 this.toolbar.show(new ToolbarLayout({ | ||||
|                     left   : | ||||
|                         [ | ||||
|                             leftSideButtons | ||||
|                         ], | ||||
|                     context: this | ||||
|                 })); | ||||
|             }, | ||||
|  | ||||
|             _refreshTable: function (buttonContext) { | ||||
|                 this.collection.state.currentPage = 1; | ||||
|                 var promise = this.collection.fetch({ reset: true }); | ||||
|  | ||||
|                 if (buttonContext) { | ||||
|                     buttonContext.ui.icon.spinForPromise(promise); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             _commandComplete: function (options) { | ||||
|                 if (options.command.get('name') === 'clearblacklist') { | ||||
|                     this._refreshTable(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template         : 'Activity/Blacklist/BlacklistLayoutTemplate', | ||||
|     regions          : { | ||||
|         blacklist : '#x-blacklist', | ||||
|         toolbar   : '#x-toolbar', | ||||
|         pager     : '#x-pager' | ||||
|     }, | ||||
|     columns          : [{ | ||||
|         name  : 'series', | ||||
|         label : 'Series', | ||||
|         cell  : SeriesTitleCell | ||||
|     }, { | ||||
|         name  : 'sourceTitle', | ||||
|         label : 'Source Title', | ||||
|         cell  : 'string' | ||||
|     }, { | ||||
|         name     : 'quality', | ||||
|         label    : 'Quality', | ||||
|         cell     : QualityCell, | ||||
|         sortable : false | ||||
|     }, { | ||||
|         name  : 'date', | ||||
|         label : 'Date', | ||||
|         cell  : RelativeDateCell | ||||
|     }, { | ||||
|         name     : 'this', | ||||
|         label    : '', | ||||
|         cell     : BlacklistActionsCell, | ||||
|         sortable : false | ||||
|     }], | ||||
|     initialize       : function(){ | ||||
|         this.collection = new BlacklistCollection({tableName : 'blacklist'}); | ||||
|         this.listenTo(this.collection, 'sync', this._showTable); | ||||
|         this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete); | ||||
|     }, | ||||
|     onShow           : function(){ | ||||
|         this.blacklist.show(new LoadingView()); | ||||
|         this._showToolbar(); | ||||
|         this.collection.fetch(); | ||||
|     }, | ||||
|     _showTable       : function(collection){ | ||||
|         this.blacklist.show(new Backgrid.Grid({ | ||||
|             columns    : this.columns, | ||||
|             collection : collection, | ||||
|             className  : 'table table-hover' | ||||
|         })); | ||||
|         this.pager.show(new GridPager({ | ||||
|             columns    : this.columns, | ||||
|             collection : collection | ||||
|         })); | ||||
|     }, | ||||
|     _showToolbar     : function(){ | ||||
|         var leftSideButtons = { | ||||
|             type       : 'default', | ||||
|             storeState : false, | ||||
|             items      : [{ | ||||
|                 title   : 'Clear Blacklist', | ||||
|                 icon    : 'icon-trash', | ||||
|                 command : 'clearBlacklist' | ||||
|             }] | ||||
|         }; | ||||
|         this.toolbar.show(new ToolbarLayout({ | ||||
|             left    : [leftSideButtons], | ||||
|             context : this | ||||
|         })); | ||||
|     }, | ||||
|     _refreshTable    : function(buttonContext){ | ||||
|         this.collection.state.currentPage = 1; | ||||
|         var promise = this.collection.fetch({reset : true}); | ||||
|         if(buttonContext) { | ||||
|             buttonContext.ui.icon.spinForPromise(promise); | ||||
|         } | ||||
|     }, | ||||
|     _commandComplete : function(options){ | ||||
|         if(options.command.get('name') === 'clearblacklist') { | ||||
|             this._refreshTable(); | ||||
|         } | ||||
|     } | ||||
| }); | ||||
| @@ -1,21 +1,14 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backbone', | ||||
|         'Series/SeriesCollection' | ||||
|     ], function (Backbone, SeriesCollection) { | ||||
|         return Backbone.Model.extend({ | ||||
| var Backbone = require('backbone'); | ||||
| var SeriesCollection = require('../../Series/SeriesCollection'); | ||||
|  | ||||
|             //Hack to deal with Backbone 1.0's bug | ||||
|             initialize: function () { | ||||
|                 this.url = function () { | ||||
|                     return this.collection.url + '/' + this.get('id'); | ||||
|                 }; | ||||
|             }, | ||||
|  | ||||
|             parse: function (model) { | ||||
|                 model.series = SeriesCollection.get(model.seriesId); | ||||
|                 return model; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Backbone.Model.extend({ | ||||
|     initialize : function(){ | ||||
|         this.url = function(){ | ||||
|             return this.collection.url + '/' + this.get('id'); | ||||
|         }; | ||||
|     }, | ||||
|     parse      : function(model){ | ||||
|         model.series = SeriesCollection.get(model.seriesId); | ||||
|         return model; | ||||
|     } | ||||
| }); | ||||
| @@ -1,19 +1,13 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'handlebars' | ||||
|     ], function (Handlebars) { | ||||
| var Handlebars = require('handlebars'); | ||||
|  | ||||
|         Handlebars.registerHelper('historyAge', function () { | ||||
|  | ||||
|             var unit = 'days'; | ||||
|             var age = this.age; | ||||
|  | ||||
|             if (age < 2) { | ||||
|                 unit = 'hours'; | ||||
|                 age = parseFloat(this.ageHours).toFixed(1); | ||||
|             } | ||||
|  | ||||
|             return new Handlebars.SafeString('<dt>Age (when grabbed):</dt><dd>{0} {1}</dd>'.format(age, unit)); | ||||
|         }); | ||||
| module.exports = (function(){ | ||||
|     Handlebars.registerHelper('historyAge', function(){ | ||||
|         var unit = 'days'; | ||||
|         var age = this.age; | ||||
|         if(age < 2) { | ||||
|             unit = 'hours'; | ||||
|             age = parseFloat(this.ageHours).toFixed(1); | ||||
|         } | ||||
|         return new Handlebars.SafeString('<dt>Age (when grabbed):</dt><dd>{0} {1}</dd>'.format(age, unit)); | ||||
|     }); | ||||
| }).call(this); | ||||
| @@ -1,40 +1,23 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'jquery', | ||||
|         'vent', | ||||
|         'marionette', | ||||
|         'Activity/History/Details/HistoryDetailsView' | ||||
|     ], function ($, vent, Marionette, HistoryDetailsView) { | ||||
| var $ = require('jquery'); | ||||
| var vent = require('../../../vent'); | ||||
| var Marionette = require('marionette'); | ||||
| var HistoryDetailsView = require('./HistoryDetailsView'); | ||||
|  | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'Activity/History/Details/HistoryDetailsLayoutTemplate', | ||||
|  | ||||
|             regions: { | ||||
|                 bodyRegion: '.modal-body' | ||||
|             }, | ||||
|  | ||||
|             events: { | ||||
|                 'click .x-mark-as-failed': '_markAsFailed' | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 this.bodyRegion.show(new HistoryDetailsView({ model: this.model })); | ||||
|             }, | ||||
|  | ||||
|             _markAsFailed: function () { | ||||
|                 var url = window.NzbDrone.ApiRoot + '/history/failed'; | ||||
|                 var data = { | ||||
|                     id: this.model.get('id') | ||||
|                 }; | ||||
|  | ||||
|                 $.ajax({ | ||||
|                     url: url, | ||||
|                     type: 'POST', | ||||
|                     data: data | ||||
|                 }); | ||||
|  | ||||
|                 vent.trigger(vent.Commands.CloseModalCommand); | ||||
|             } | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template      : 'Activity/History/Details/HistoryDetailsLayoutTemplate', | ||||
|     regions       : {bodyRegion : '.modal-body'}, | ||||
|     events        : {"click .x-mark-as-failed" : '_markAsFailed'}, | ||||
|     onShow        : function(){ | ||||
|         this.bodyRegion.show(new HistoryDetailsView({model : this.model})); | ||||
|     }, | ||||
|     _markAsFailed : function(){ | ||||
|         var url = window.NzbDrone.ApiRoot + '/history/failed'; | ||||
|         var data = {id : this.model.get('id')}; | ||||
|         $.ajax({ | ||||
|             url  : url, | ||||
|             type : 'POST', | ||||
|             data : data | ||||
|         }); | ||||
|     }); | ||||
|         vent.trigger(vent.Commands.CloseModalCommand); | ||||
|     } | ||||
| }); | ||||
| @@ -1,11 +1,4 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'Activity/History/Details/HistoryDetailsAge' | ||||
|     ], function (Marionette) { | ||||
| var Marionette = require('marionette'); | ||||
| require('./HistoryDetailsAge'); | ||||
|  | ||||
|         return Marionette.ItemView.extend({ | ||||
|             template: 'Activity/History/Details/HistoryDetailsViewTemplate' | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.ItemView.extend({template : 'Activity/History/Details/HistoryDetailsViewTemplate'}); | ||||
| @@ -1,70 +1,56 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'Activity/History/HistoryModel', | ||||
|         'backbone.pageable', | ||||
|         'Mixins/AsFilteredCollection', | ||||
|         'Mixins/AsSortedCollection', | ||||
|         'Mixins/AsPersistedStateCollection' | ||||
|     ], function (HistoryModel, PageableCollection, AsFilteredCollection, AsSortedCollection, AsPersistedStateCollection) { | ||||
|         var Collection = PageableCollection.extend({ | ||||
|             url  : window.NzbDrone.ApiRoot + '/history', | ||||
|             model: HistoryModel, | ||||
| var HistoryModel = require('./HistoryModel'); | ||||
| var PageableCollection = require('backbone.pageable'); | ||||
| var AsFilteredCollection = require('../../Mixins/AsFilteredCollection'); | ||||
| var AsSortedCollection = require('../../Mixins/AsSortedCollection'); | ||||
| var AsPersistedStateCollection = require('../../Mixins/AsPersistedStateCollection'); | ||||
|  | ||||
|             state: { | ||||
|                 pageSize: 15, | ||||
|                 sortKey : 'date', | ||||
|                 order   : 1 | ||||
|             }, | ||||
|  | ||||
|             queryParams: { | ||||
|                 totalPages  : null, | ||||
|                 totalRecords: null, | ||||
|                 pageSize    : 'pageSize', | ||||
|                 sortKey     : 'sortKey', | ||||
|                 order       : 'sortDir', | ||||
|                 directions  : { | ||||
|                     '-1': 'asc', | ||||
|                     '1' : 'desc' | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             filterModes: { | ||||
|                 'all'      : [null, null], | ||||
|                 'grabbed'  : ['eventType', '1'], | ||||
|                 'imported' : ['eventType', '3'], | ||||
|                 'failed'   : ['eventType', '4'], | ||||
|                 'deleted'  : ['eventType', '5'] | ||||
|             }, | ||||
|  | ||||
|             sortMappings: { | ||||
|                 'series'   : { sortKey: 'series.sortTitle' } | ||||
|             }, | ||||
|  | ||||
|             initialize: function (options) { | ||||
|                 delete this.queryParams.episodeId; | ||||
|  | ||||
|                 if (options) { | ||||
|                     if (options.episodeId) { | ||||
|                         this.queryParams.episodeId = options.episodeId; | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             parseState: function (resp) { | ||||
|                 return { totalRecords: resp.totalRecords }; | ||||
|             }, | ||||
|  | ||||
|             parseRecords: function (resp) { | ||||
|                 if (resp) { | ||||
|                     return resp.records; | ||||
|                 } | ||||
|  | ||||
|                 return resp; | ||||
| module.exports = (function(){ | ||||
|     var Collection = PageableCollection.extend({ | ||||
|         url          : window.NzbDrone.ApiRoot + '/history', | ||||
|         model        : HistoryModel, | ||||
|         state        : { | ||||
|             pageSize : 15, | ||||
|             sortKey  : 'date', | ||||
|             order    : 1 | ||||
|         }, | ||||
|         queryParams  : { | ||||
|             totalPages   : null, | ||||
|             totalRecords : null, | ||||
|             pageSize     : 'pageSize', | ||||
|             sortKey      : 'sortKey', | ||||
|             order        : 'sortDir', | ||||
|             directions   : { | ||||
|                 "-1" : 'asc', | ||||
|                 "1"  : 'desc' | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         Collection = AsFilteredCollection.call(Collection); | ||||
|         Collection = AsSortedCollection.call(Collection); | ||||
|         return AsPersistedStateCollection.call(Collection); | ||||
|         }, | ||||
|         filterModes  : { | ||||
|             "all"      : [null, null], | ||||
|             "grabbed"  : ['eventType', '1'], | ||||
|             "imported" : ['eventType', '3'], | ||||
|             "failed"   : ['eventType', '4'], | ||||
|             "deleted"  : ['eventType', '5'] | ||||
|         }, | ||||
|         sortMappings : {"series" : {sortKey : 'series.sortTitle'}}, | ||||
|         initialize   : function(options){ | ||||
|             delete this.queryParams.episodeId; | ||||
|             if(options) { | ||||
|                 if(options.episodeId) { | ||||
|                     this.queryParams.episodeId = options.episodeId; | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         parseState   : function(resp){ | ||||
|             return {totalRecords : resp.totalRecords}; | ||||
|         }, | ||||
|         parseRecords : function(resp){ | ||||
|             if(resp) { | ||||
|                 return resp.records; | ||||
|             } | ||||
|             return resp; | ||||
|         } | ||||
|     }); | ||||
|     Collection = AsFilteredCollection.call(Collection); | ||||
|     Collection = AsSortedCollection.call(Collection); | ||||
|     return AsPersistedStateCollection.call(Collection); | ||||
| }).call(this); | ||||
| @@ -1,27 +1,15 @@ | ||||
| 'use strict'; | ||||
| var vent = require('../../vent'); | ||||
| var NzbDroneCell = require('../../Cells/NzbDroneCell'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'vent', | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function (vent, NzbDroneCell) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className: 'history-details-cell', | ||||
|  | ||||
|             events: { | ||||
|                 'click': '_showDetails' | ||||
|             }, | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|                 this.$el.html('<i class="icon-info-sign"></i>'); | ||||
|  | ||||
|                 return this; | ||||
|             }, | ||||
|  | ||||
|             _showDetails: function () { | ||||
|                 vent.trigger(vent.Commands.ShowHistoryDetails, { model: this.model }); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className    : 'history-details-cell', | ||||
|     events       : {"click" : '_showDetails'}, | ||||
|     render       : function(){ | ||||
|         this.$el.empty(); | ||||
|         this.$el.html('<i class="icon-info-sign"></i>'); | ||||
|         return this; | ||||
|     }, | ||||
|     _showDetails : function(){ | ||||
|         vent.trigger(vent.Commands.ShowHistoryDetails, {model : this.model}); | ||||
|     } | ||||
| }); | ||||
| @@ -1,173 +1,126 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'backgrid', | ||||
|         'Activity/History/HistoryCollection', | ||||
|         'Cells/EventTypeCell', | ||||
|         'Cells/SeriesTitleCell', | ||||
|         'Cells/EpisodeNumberCell', | ||||
|         'Cells/EpisodeTitleCell', | ||||
|         'Activity/History/HistoryQualityCell', | ||||
|         'Cells/RelativeDateCell', | ||||
|         'Activity/History/HistoryDetailsCell', | ||||
|         'Shared/Grid/Pager', | ||||
|         'Shared/Toolbar/ToolbarLayout', | ||||
|         'Shared/LoadingView' | ||||
|     ], function (Marionette, | ||||
|                  Backgrid, | ||||
|                  HistoryCollection, | ||||
|                  EventTypeCell, | ||||
|                  SeriesTitleCell, | ||||
|                  EpisodeNumberCell, | ||||
|                  EpisodeTitleCell, | ||||
|                  HistoryQualityCell, | ||||
|                  RelativeDateCell, | ||||
|                  HistoryDetailsCell, | ||||
|                  GridPager, | ||||
|                  ToolbarLayout, | ||||
|                  LoadingView) { | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'Activity/History/HistoryLayoutTemplate', | ||||
| var Marionette = require('marionette'); | ||||
| var Backgrid = require('backgrid'); | ||||
| var HistoryCollection = require('./HistoryCollection'); | ||||
| var EventTypeCell = require('../../Cells/EventTypeCell'); | ||||
| var SeriesTitleCell = require('../../Cells/SeriesTitleCell'); | ||||
| var EpisodeNumberCell = require('../../Cells/EpisodeNumberCell'); | ||||
| var EpisodeTitleCell = require('../../Cells/EpisodeTitleCell'); | ||||
| var HistoryQualityCell = require('./HistoryQualityCell'); | ||||
| var RelativeDateCell = require('../../Cells/RelativeDateCell'); | ||||
| var HistoryDetailsCell = require('./HistoryDetailsCell'); | ||||
| var GridPager = require('../../Shared/Grid/Pager'); | ||||
| var ToolbarLayout = require('../../Shared/Toolbar/ToolbarLayout'); | ||||
| var LoadingView = require('../../Shared/LoadingView'); | ||||
|  | ||||
|             regions: { | ||||
|                 history: '#x-history', | ||||
|                 toolbar: '#x-history-toolbar', | ||||
|                 pager  : '#x-history-pager' | ||||
|             }, | ||||
|  | ||||
|             columns: | ||||
|                 [ | ||||
|                     { | ||||
|                         name      : 'eventType', | ||||
|                         label     : '', | ||||
|                         cell      : EventTypeCell, | ||||
|                         cellValue : 'this' | ||||
|                     }, | ||||
|                     { | ||||
|                         name      : 'series', | ||||
|                         label     : 'Series', | ||||
|                         cell      : SeriesTitleCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name      : 'episode', | ||||
|                         label     : 'Episode', | ||||
|                         cell      : EpisodeNumberCell, | ||||
|                         sortable  : false | ||||
|                     }, | ||||
|                     { | ||||
|                         name      : 'episode', | ||||
|                         label     : 'Episode Title', | ||||
|                         cell      : EpisodeTitleCell, | ||||
|                         sortable  : false | ||||
|                     }, | ||||
|                     { | ||||
|                         name      : 'this', | ||||
|                         label     : 'Quality', | ||||
|                         cell      : HistoryQualityCell, | ||||
|                         sortable  : false | ||||
|                     }, | ||||
|                     { | ||||
|                         name      : 'date', | ||||
|                         label     : 'Date', | ||||
|                         cell      : RelativeDateCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name      : 'this', | ||||
|                         label     : '', | ||||
|                         cell      : HistoryDetailsCell, | ||||
|                         sortable  : false | ||||
|                     } | ||||
|                 ], | ||||
|  | ||||
|             initialize: function () { | ||||
|                 this.collection = new HistoryCollection({ tableName: 'history' }); | ||||
|                 this.listenTo(this.collection, 'sync', this._showTable); | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 this.history.show(new LoadingView()); | ||||
|                 this._showToolbar(); | ||||
|             }, | ||||
|  | ||||
|             _showTable: function (collection) { | ||||
|  | ||||
|                 this.history.show(new Backgrid.Grid({ | ||||
|                     columns   : this.columns, | ||||
|                     collection: collection, | ||||
|                     className : 'table table-hover' | ||||
|                 })); | ||||
|  | ||||
|                 this.pager.show(new GridPager({ | ||||
|                     columns   : this.columns, | ||||
|                     collection: collection | ||||
|                 })); | ||||
|             }, | ||||
|  | ||||
|             _showToolbar: function () { | ||||
|                 var filterOptions = { | ||||
|                     type          : 'radio', | ||||
|                     storeState    : true, | ||||
|                     menuKey       : 'history.filterMode', | ||||
|                     defaultAction : 'all', | ||||
|                     items         : | ||||
|                         [ | ||||
|                             { | ||||
|                                 key      : 'all', | ||||
|                                 title    : '', | ||||
|                                 tooltip  : 'All', | ||||
|                                 icon     : 'icon-circle-blank', | ||||
|                                 callback : this._setFilter | ||||
|                             }, | ||||
|                             { | ||||
|                                 key      : 'grabbed', | ||||
|                                 title    : '', | ||||
|                                 tooltip  : 'Grabbed', | ||||
|                                 icon     : 'icon-nd-downloading', | ||||
|                                 callback : this._setFilter | ||||
|                             }, | ||||
|                             { | ||||
|                                 key      : 'imported', | ||||
|                                 title    : '', | ||||
|                                 tooltip  : 'Imported', | ||||
|                                 icon     : 'icon-nd-imported', | ||||
|                                 callback : this._setFilter | ||||
|                             }, | ||||
|                             { | ||||
|                                 key      : 'failed', | ||||
|                                 title    : '', | ||||
|                                 tooltip  : 'Failed', | ||||
|                                 icon     : 'icon-nd-download-failed', | ||||
|                                 callback : this._setFilter | ||||
|                             }, | ||||
|                             { | ||||
|                                 key      : 'deleted', | ||||
|                                 title    : '', | ||||
|                                 tooltip  : 'Deleted', | ||||
|                                 icon     : 'icon-nd-deleted', | ||||
|                                 callback : this._setFilter | ||||
|                             } | ||||
|                         ] | ||||
|                 }; | ||||
|  | ||||
|                 this.toolbar.show(new ToolbarLayout({ | ||||
|                     right  : | ||||
|                         [ | ||||
|                             filterOptions | ||||
|                         ], | ||||
|                     context: this | ||||
|                 })); | ||||
|             }, | ||||
|  | ||||
|             _setFilter: function(buttonContext) { | ||||
|                 var mode = buttonContext.model.get('key'); | ||||
|  | ||||
|                 this.collection.state.currentPage = 1; | ||||
|                 var promise = this.collection.setFilterMode(mode); | ||||
|  | ||||
|                 if (buttonContext) { | ||||
|                     buttonContext.ui.icon.spinForPromise(promise); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template     : 'Activity/History/HistoryLayoutTemplate', | ||||
|     regions      : { | ||||
|         history : '#x-history', | ||||
|         toolbar : '#x-history-toolbar', | ||||
|         pager   : '#x-history-pager' | ||||
|     }, | ||||
|     columns      : [{ | ||||
|         name      : 'eventType', | ||||
|         label     : '', | ||||
|         cell      : EventTypeCell, | ||||
|         cellValue : 'this' | ||||
|     }, { | ||||
|         name  : 'series', | ||||
|         label : 'Series', | ||||
|         cell  : SeriesTitleCell | ||||
|     }, { | ||||
|         name     : 'episode', | ||||
|         label    : 'Episode', | ||||
|         cell     : EpisodeNumberCell, | ||||
|         sortable : false | ||||
|     }, { | ||||
|         name     : 'episode', | ||||
|         label    : 'Episode Title', | ||||
|         cell     : EpisodeTitleCell, | ||||
|         sortable : false | ||||
|     }, { | ||||
|         name     : 'this', | ||||
|         label    : 'Quality', | ||||
|         cell     : HistoryQualityCell, | ||||
|         sortable : false | ||||
|     }, { | ||||
|         name  : 'date', | ||||
|         label : 'Date', | ||||
|         cell  : RelativeDateCell | ||||
|     }, { | ||||
|         name     : 'this', | ||||
|         label    : '', | ||||
|         cell     : HistoryDetailsCell, | ||||
|         sortable : false | ||||
|     }], | ||||
|     initialize   : function(){ | ||||
|         this.collection = new HistoryCollection({tableName : 'history'}); | ||||
|         this.listenTo(this.collection, 'sync', this._showTable); | ||||
|     }, | ||||
|     onShow       : function(){ | ||||
|         this.history.show(new LoadingView()); | ||||
|         this._showToolbar(); | ||||
|     }, | ||||
|     _showTable   : function(collection){ | ||||
|         this.history.show(new Backgrid.Grid({ | ||||
|             columns    : this.columns, | ||||
|             collection : collection, | ||||
|             className  : 'table table-hover' | ||||
|         })); | ||||
|         this.pager.show(new GridPager({ | ||||
|             columns    : this.columns, | ||||
|             collection : collection | ||||
|         })); | ||||
|     }, | ||||
|     _showToolbar : function(){ | ||||
|         var filterOptions = { | ||||
|             type          : 'radio', | ||||
|             storeState    : true, | ||||
|             menuKey       : 'history.filterMode', | ||||
|             defaultAction : 'all', | ||||
|             items         : [{ | ||||
|                 key      : 'all', | ||||
|                 title    : '', | ||||
|                 tooltip  : 'All', | ||||
|                 icon     : 'icon-circle-blank', | ||||
|                 callback : this._setFilter | ||||
|             }, { | ||||
|                 key      : 'grabbed', | ||||
|                 title    : '', | ||||
|                 tooltip  : 'Grabbed', | ||||
|                 icon     : 'icon-nd-downloading', | ||||
|                 callback : this._setFilter | ||||
|             }, { | ||||
|                 key      : 'imported', | ||||
|                 title    : '', | ||||
|                 tooltip  : 'Imported', | ||||
|                 icon     : 'icon-nd-imported', | ||||
|                 callback : this._setFilter | ||||
|             }, { | ||||
|                 key      : 'failed', | ||||
|                 title    : '', | ||||
|                 tooltip  : 'Failed', | ||||
|                 icon     : 'icon-nd-download-failed', | ||||
|                 callback : this._setFilter | ||||
|             }, { | ||||
|                 key      : 'deleted', | ||||
|                 title    : '', | ||||
|                 tooltip  : 'Deleted', | ||||
|                 icon     : 'icon-nd-deleted', | ||||
|                 callback : this._setFilter | ||||
|             }] | ||||
|         }; | ||||
|         this.toolbar.show(new ToolbarLayout({ | ||||
|             right   : [filterOptions], | ||||
|             context : this | ||||
|         })); | ||||
|     }, | ||||
|     _setFilter   : function(buttonContext){ | ||||
|         var mode = buttonContext.model.get('key'); | ||||
|         this.collection.state.currentPage = 1; | ||||
|         var promise = this.collection.setFilterMode(mode); | ||||
|         if(buttonContext) { | ||||
|             buttonContext.ui.icon.spinForPromise(promise); | ||||
|         } | ||||
|     } | ||||
| }); | ||||
| @@ -1,16 +1,12 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backbone', | ||||
|         'Series/SeriesModel', | ||||
|         'Series/EpisodeModel' | ||||
|     ], function (Backbone, SeriesModel, EpisodeModel) { | ||||
|         return Backbone.Model.extend({ | ||||
|             parse: function (model) { | ||||
|                 model.series = new SeriesModel(model.series); | ||||
|                 model.episode = new EpisodeModel(model.episode); | ||||
|                 model.episode.set('series', model.series); | ||||
|                 return model; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| var Backbone = require('backbone'); | ||||
| var SeriesModel = require('../../Series/SeriesModel'); | ||||
| var EpisodeModel = require('../../Series/EpisodeModel'); | ||||
|  | ||||
| module.exports = Backbone.Model.extend({ | ||||
|     parse : function(model){ | ||||
|         model.series = new SeriesModel(model.series); | ||||
|         model.episode = new EpisodeModel(model.episode); | ||||
|         model.episode.set('series', model.series); | ||||
|         return model; | ||||
|     } | ||||
| }); | ||||
| @@ -1,36 +1,24 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function (NzbDroneCell) { | ||||
|         return NzbDroneCell.extend({ | ||||
| var NzbDroneCell = require('../../Cells/NzbDroneCell'); | ||||
|  | ||||
|             className: 'history-quality-cell', | ||||
|  | ||||
|             render: function () { | ||||
|  | ||||
|                 var title = ''; | ||||
|                 var quality = this.model.get('quality'); | ||||
|                 var revision = quality.revision; | ||||
|  | ||||
|                 if (revision.real && revision.real > 0) { | ||||
|                     title += ' REAL'; | ||||
|                 } | ||||
|  | ||||
|                 if (revision.version && revision.version > 1) { | ||||
|                     title += ' PROPER'; | ||||
|                 } | ||||
|  | ||||
|                 title = title.trim(); | ||||
|  | ||||
|                 if (this.model.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 this; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className : 'history-quality-cell', | ||||
|     render    : function(){ | ||||
|         var title = ''; | ||||
|         var quality = this.model.get('quality'); | ||||
|         var revision = quality.revision; | ||||
|         if(revision.real && revision.real > 0) { | ||||
|             title += ' REAL'; | ||||
|         } | ||||
|         if(revision.version && revision.version > 1) { | ||||
|             title += ' PROPER'; | ||||
|         } | ||||
|         title = title.trim(); | ||||
|         if(this.model.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 this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,29 +1,16 @@ | ||||
| 'use strict'; | ||||
| var NzbDroneCell = require('../../Cells/NzbDroneCell'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function (NzbDroneCell) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className: 'progress-cell', | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|  | ||||
|                 if (this.cellValue) { | ||||
|  | ||||
|                     var status = this.model.get('status').toLowerCase(); | ||||
|  | ||||
|                     if (status === 'downloading') { | ||||
|                         var progress = 100 - (this.model.get('sizeleft') / this.model.get('size') * 100); | ||||
|  | ||||
|                         this.$el.html('<div class="progress" title="{0}%">'.format(progress.toFixed(1)) + | ||||
|                         '<div class="progress-bar progress-bar-purple" style="width: {0}%;"></div></div>'.format(progress)); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 return this; | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className : 'progress-cell', | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         if(this.cellValue) { | ||||
|             var status = this.model.get('status').toLowerCase(); | ||||
|             if(status === 'downloading') { | ||||
|                 var progress = 100 - this.model.get('sizeleft') / this.model.get('size') * 100; | ||||
|                 this.$el.html('<div class="progress" title="{0}%">'.format(progress.toFixed(1)) + '<div class="progress-bar progress-bar-purple" style="width: {0}%;"></div></div>'.format(progress)); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,31 +1,22 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'underscore', | ||||
|         'backbone', | ||||
|         'backbone.pageable', | ||||
|         'Activity/Queue/QueueModel', | ||||
|         'Mixins/backbone.signalr.mixin' | ||||
|     ], function (_, Backbone, PageableCollection, QueueModel) { | ||||
|         var QueueCollection = PageableCollection.extend({ | ||||
|             url  : window.NzbDrone.ApiRoot + '/queue', | ||||
|             model: QueueModel, | ||||
| var _ = require('underscore'); | ||||
| var Backbone = require('backbone'); | ||||
| var PageableCollection = require('backbone.pageable'); | ||||
| var QueueModel = require('./QueueModel'); | ||||
| require('../../Mixins/backbone.signalr.mixin'); | ||||
|  | ||||
|             state: { | ||||
|                 pageSize: 15 | ||||
|             }, | ||||
|  | ||||
|             mode: 'client', | ||||
|  | ||||
|             findEpisode: function (episodeId) { | ||||
|                 return _.find(this.fullCollection.models, function (queueModel) { | ||||
|                     return queueModel.get('episode').id === episodeId; | ||||
|                 }); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         var collection = new QueueCollection().bindSignalR(); | ||||
|         collection.fetch(); | ||||
|  | ||||
|         return collection; | ||||
| module.exports = (function(){ | ||||
|     var QueueCollection = PageableCollection.extend({ | ||||
|         url         : window.NzbDrone.ApiRoot + '/queue', | ||||
|         model       : QueueModel, | ||||
|         state       : {pageSize : 15}, | ||||
|         mode        : 'client', | ||||
|         findEpisode : function(episodeId){ | ||||
|             return _.find(this.fullCollection.models, function(queueModel){ | ||||
|                 return queueModel.get('episode').id === episodeId; | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
|     var collection = new QueueCollection().bindSignalR(); | ||||
|     collection.fetch(); | ||||
|     return collection; | ||||
| }).call(this); | ||||
| @@ -1,16 +1,12 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backbone', | ||||
|         'Series/SeriesModel', | ||||
|         'Series/EpisodeModel' | ||||
|     ], function (Backbone, SeriesModel, EpisodeModel) { | ||||
|         return Backbone.Model.extend({ | ||||
|             parse: function (model) { | ||||
|                 model.series = new SeriesModel(model.series); | ||||
|                 model.episode = new EpisodeModel(model.episode); | ||||
|                 model.episode.set('series', model.series); | ||||
|                 return model; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| var Backbone = require('backbone'); | ||||
| var SeriesModel = require('../../Series/SeriesModel'); | ||||
| var EpisodeModel = require('../../Series/EpisodeModel'); | ||||
|  | ||||
| module.exports = Backbone.Model.extend({ | ||||
|     parse : function(model){ | ||||
|         model.series = new SeriesModel(model.series); | ||||
|         model.episode = new EpisodeModel(model.episode); | ||||
|         model.episode.set('series', model.series); | ||||
|         return model; | ||||
|     } | ||||
| }); | ||||
| @@ -1,89 +1,69 @@ | ||||
| 'use strict'; | ||||
| var Marionette = require('marionette'); | ||||
| var NzbDroneCell = require('../../Cells/NzbDroneCell'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function (Marionette, NzbDroneCell) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className : 'queue-status-cell', | ||||
|             template  : 'Activity/Queue/QueueStatusCellTemplate', | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|  | ||||
|                 if (this.cellValue) { | ||||
|                     var status = this.cellValue.get('status').toLowerCase(); | ||||
|                     var trackedDownloadStatus = this.cellValue.has('trackedDownloadStatus') ? this.cellValue.get('trackedDownloadStatus').toLowerCase() : 'ok'; | ||||
|                     var icon = 'icon-nd-downloading'; | ||||
|                     var title = 'Downloading'; | ||||
|                     var itemTitle = this.cellValue.get('title'); | ||||
|                     var content = itemTitle; | ||||
|  | ||||
|                     if (status === 'paused') { | ||||
|                         icon = 'icon-pause'; | ||||
|                         title = 'Paused'; | ||||
|                     } | ||||
|  | ||||
|                     if (status === 'queued') { | ||||
|                         icon = 'icon-cloud'; | ||||
|                         title = 'Queued'; | ||||
|                     } | ||||
|  | ||||
|                     if (status === 'completed') { | ||||
|                         icon = 'icon-inbox'; | ||||
|                         title = 'Downloaded'; | ||||
|                     } | ||||
|                      | ||||
|                     if (status === 'pending') { | ||||
|                         icon = 'icon-time'; | ||||
|                         title = 'Pending'; | ||||
|                     } | ||||
|  | ||||
|                     if (status === 'failed') { | ||||
|                         icon = 'icon-nd-download-failed'; | ||||
|                         title = 'Download failed'; | ||||
|                     } | ||||
|  | ||||
|                     if (status === 'warning') { | ||||
|                         icon = 'icon-nd-download-warning'; | ||||
|                         title = 'Download warning: check download client for more details'; | ||||
|                     } | ||||
|  | ||||
|                     if (trackedDownloadStatus === 'warning') { | ||||
|                         icon += ' icon-nd-warning'; | ||||
|  | ||||
|                         this.templateFunction = Marionette.TemplateCache.get(this.template); | ||||
|                         content = this.templateFunction(this.cellValue.toJSON()); | ||||
|                     } | ||||
|  | ||||
|                     if (trackedDownloadStatus === 'error') { | ||||
|                         if (status === 'completed') { | ||||
|                             icon = 'icon-nd-import-failed'; | ||||
|                             title = 'Import failed: ' + itemTitle; | ||||
|                         } | ||||
|                         else { | ||||
|                             icon = 'icon-nd-download-failed'; | ||||
|                             title = 'Download failed'; | ||||
|                         } | ||||
|  | ||||
|                         this.templateFunction = Marionette.TemplateCache.get(this.template); | ||||
|                         content = this.templateFunction(this.cellValue.toJSON()); | ||||
|                     } | ||||
|  | ||||
|                     this.$el.html('<i class="{0}"></i>'.format(icon)); | ||||
|                     this.$el.popover({ | ||||
|                         content  : content, | ||||
|                         html     : true, | ||||
|                         trigger  : 'hover', | ||||
|                         title    : title, | ||||
|                         placement: 'right', | ||||
|                         container: this.$el | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|                 return this; | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className : 'queue-status-cell', | ||||
|     template  : 'Activity/Queue/QueueStatusCellTemplate', | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         if(this.cellValue) { | ||||
|             var status = this.cellValue.get('status').toLowerCase(); | ||||
|             var trackedDownloadStatus = this.cellValue.has('trackedDownloadStatus') ? this.cellValue.get('trackedDownloadStatus').toLowerCase() : 'ok'; | ||||
|             var icon = 'icon-nd-downloading'; | ||||
|             var title = 'Downloading'; | ||||
|             var itemTitle = this.cellValue.get('title'); | ||||
|             var content = itemTitle; | ||||
|             if(status === 'paused') { | ||||
|                 icon = 'icon-pause'; | ||||
|                 title = 'Paused'; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|             if(status === 'queued') { | ||||
|                 icon = 'icon-cloud'; | ||||
|                 title = 'Queued'; | ||||
|             } | ||||
|             if(status === 'completed') { | ||||
|                 icon = 'icon-inbox'; | ||||
|                 title = 'Downloaded'; | ||||
|             } | ||||
|             if(status === 'pending') { | ||||
|                 icon = 'icon-time'; | ||||
|                 title = 'Pending'; | ||||
|             } | ||||
|             if(status === 'failed') { | ||||
|                 icon = 'icon-nd-download-failed'; | ||||
|                 title = 'Download failed'; | ||||
|             } | ||||
|             if(status === 'warning') { | ||||
|                 icon = 'icon-nd-download-warning'; | ||||
|                 title = 'Download warning: check download client for more details'; | ||||
|             } | ||||
|             if(trackedDownloadStatus === 'warning') { | ||||
|                 icon += ' icon-nd-warning'; | ||||
|                 this.templateFunction = Marionette.TemplateCache.get(this.template); | ||||
|                 content = this.templateFunction(this.cellValue.toJSON()); | ||||
|             } | ||||
|             if(trackedDownloadStatus === 'error') { | ||||
|                 if(status === 'completed') { | ||||
|                     icon = 'icon-nd-import-failed'; | ||||
|                     title = 'Import failed: ' + itemTitle; | ||||
|                 } | ||||
|                 else { | ||||
|                     icon = 'icon-nd-download-failed'; | ||||
|                     title = 'Download failed'; | ||||
|                 } | ||||
|                 this.templateFunction = Marionette.TemplateCache.get(this.template); | ||||
|                 content = this.templateFunction(this.cellValue.toJSON()); | ||||
|             } | ||||
|             this.$el.html('<i class="{0}"></i>'.format(icon)); | ||||
|             this.$el.popover({ | ||||
|                 content   : content, | ||||
|                 html      : true, | ||||
|                 trigger   : 'hover', | ||||
|                 title     : title, | ||||
|                 placement : 'right', | ||||
|                 container : this.$el | ||||
|             }); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,46 +1,33 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'underscore', | ||||
|         'marionette', | ||||
|         'Activity/Queue/QueueCollection' | ||||
|     ], function (_, Marionette, QueueCollection) { | ||||
|         return Marionette.ItemView.extend({ | ||||
|             tagName: 'span', | ||||
| var _ = require('underscore'); | ||||
| var Marionette = require('marionette'); | ||||
| var QueueCollection = require('./QueueCollection'); | ||||
|  | ||||
|             initialize: function () { | ||||
|                 this.listenTo(QueueCollection, 'sync', this.render); | ||||
|                 QueueCollection.fetch(); | ||||
|             }, | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|  | ||||
|                 if (QueueCollection.length === 0) { | ||||
|                     return this; | ||||
|                 } | ||||
|  | ||||
|                 var count = QueueCollection.fullCollection.length; | ||||
|                 var label = 'label-info'; | ||||
|  | ||||
|                 var errors = QueueCollection.fullCollection.some(function (model) { | ||||
|                     return model.has('trackedDownloadStatus') && model.get('trackedDownloadStatus').toLowerCase() === 'error'; | ||||
|                 }); | ||||
|  | ||||
|                 var warnings = QueueCollection.fullCollection.some(function (model) { | ||||
|                     return model.has('trackedDownloadStatus') && model.get('trackedDownloadStatus').toLowerCase() === 'warning'; | ||||
|                 }); | ||||
|  | ||||
|                 if (errors) { | ||||
|                     label = 'label-danger'; | ||||
|                 } | ||||
|  | ||||
|                 else if (warnings) { | ||||
|                     label = 'label-warning'; | ||||
|                 } | ||||
|  | ||||
|                 this.$el.html('<span class="label {0}">{1}</span>'.format(label, count)); | ||||
|                 return this; | ||||
|             } | ||||
| module.exports = Marionette.ItemView.extend({ | ||||
|     tagName    : 'span', | ||||
|     initialize : function(){ | ||||
|         this.listenTo(QueueCollection, 'sync', this.render); | ||||
|         QueueCollection.fetch(); | ||||
|     }, | ||||
|     render     : function(){ | ||||
|         this.$el.empty(); | ||||
|         if(QueueCollection.length === 0) { | ||||
|             return this; | ||||
|         } | ||||
|         var count = QueueCollection.fullCollection.length; | ||||
|         var label = 'label-info'; | ||||
|         var errors = QueueCollection.fullCollection.some(function(model){ | ||||
|             return model.has('trackedDownloadStatus') && model.get('trackedDownloadStatus').toLowerCase() === 'error'; | ||||
|         }); | ||||
|     }); | ||||
|         var warnings = QueueCollection.fullCollection.some(function(model){ | ||||
|             return model.has('trackedDownloadStatus') && model.get('trackedDownloadStatus').toLowerCase() === 'warning'; | ||||
|         }); | ||||
|         if(errors) { | ||||
|             label = 'label-danger'; | ||||
|         } | ||||
|         else if(warnings) { | ||||
|             label = 'label-warning'; | ||||
|         } | ||||
|         this.$el.html('<span class="label {0}">{1}</span>'.format(label, count)); | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,47 +1,32 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'Cells/NzbDroneCell', | ||||
|         'filesize', | ||||
|         'moment', | ||||
|         'Shared/UiSettingsModel', | ||||
|         'Shared/FormatHelpers' | ||||
|     ], function (NzbDroneCell, fileSize, moment, UiSettingsModel, FormatHelpers) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className: 'timeleft-cell', | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|  | ||||
|                 if (this.cellValue) { | ||||
|  | ||||
|                     //If the release is pending we want to use the timeleft as the time it will be processed at | ||||
|                     if (this.cellValue.get('status').toLowerCase() === 'pending') { | ||||
|                         var ect = this.cellValue.get('estimatedCompletionTime'); | ||||
|                         var time = '{0} at {1}'.format(FormatHelpers.relativeDate(ect), moment(ect).format(UiSettingsModel.time(true, false))); | ||||
|  | ||||
|                         this.$el.html('-'); | ||||
|                         this.$el.attr('title', 'Will be processed during the first RSS Sync after {0}'.format(time)); | ||||
|                         this.$el.attr('data-container', 'body'); | ||||
|  | ||||
|                         return this; | ||||
|                     } | ||||
|  | ||||
|                     var timeleft = this.cellValue.get('timeleft'); | ||||
|                     var totalSize = fileSize(this.cellValue.get('size'), 1, false); | ||||
|                     var remainingSize = fileSize(this.cellValue.get('sizeleft'), 1, false); | ||||
|  | ||||
|                     if (timeleft === undefined) { | ||||
|                         this.$el.html('-'); | ||||
|                     } | ||||
|                     else { | ||||
|                         this.$el.html('<span title="{1} / {2}">{0}</span>'.format(timeleft, remainingSize, totalSize)); | ||||
|                     } | ||||
|                 } | ||||
| var NzbDroneCell = require('../../Cells/NzbDroneCell'); | ||||
| var fileSize = require('filesize'); | ||||
| var moment = require('moment'); | ||||
| var UiSettingsModel = require('../../Shared/UiSettingsModel'); | ||||
| var FormatHelpers = require('../../Shared/FormatHelpers'); | ||||
|  | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className : 'timeleft-cell', | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         if(this.cellValue) { | ||||
|             if(this.cellValue.get('status').toLowerCase() === 'pending') { | ||||
|                 var ect = this.cellValue.get('estimatedCompletionTime'); | ||||
|                 var time = '{0} at {1}'.format(FormatHelpers.relativeDate(ect), moment(ect).format(UiSettingsModel.time(true, false))); | ||||
|                 this.$el.html('-'); | ||||
|                 this.$el.attr('title', 'Will be processed during the first RSS Sync after {0}'.format(time)); | ||||
|                 this.$el.attr('data-container', 'body'); | ||||
|                 return this; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|             var timeleft = this.cellValue.get('timeleft'); | ||||
|             var totalSize = fileSize(this.cellValue.get('size'), 1, false); | ||||
|             var remainingSize = fileSize(this.cellValue.get('sizeleft'), 1, false); | ||||
|             if(timeleft === undefined) { | ||||
|                 this.$el.html('-'); | ||||
|             } | ||||
|             else { | ||||
|                 this.$el.html('<span title="{1} / {2}">{0}</span>'.format(timeleft, remainingSize, totalSize)); | ||||
|             } | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,27 +1,18 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backbone', | ||||
|         'Series/SeriesModel', | ||||
|         'underscore' | ||||
|     ], function (Backbone, SeriesModel, _) { | ||||
|         return Backbone.Collection.extend({ | ||||
|             url  : window.NzbDrone.ApiRoot + '/series/lookup', | ||||
|             model: SeriesModel, | ||||
| var Backbone = require('backbone'); | ||||
| var SeriesModel = require('../Series/SeriesModel'); | ||||
| var _ = require('underscore'); | ||||
|  | ||||
|             parse: function (response) { | ||||
|  | ||||
|                 var self = this; | ||||
|  | ||||
|                 _.each(response, function (model) { | ||||
|                     model.id = undefined; | ||||
|  | ||||
|                     if (self.unmappedFolderModel) { | ||||
|                         model.path = self.unmappedFolderModel.get('folder').path; | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|                 return response; | ||||
| module.exports = Backbone.Collection.extend({ | ||||
|     url   : window.NzbDrone.ApiRoot + '/series/lookup', | ||||
|     model : SeriesModel, | ||||
|     parse : function(response){ | ||||
|         var self = this; | ||||
|         _.each(response, function(model){ | ||||
|             model.id = undefined; | ||||
|             if(self.unmappedFolderModel) { | ||||
|                 model.path = self.unmappedFolderModel.get('folder').path; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|         return response; | ||||
|     } | ||||
| }); | ||||
| @@ -1,67 +1,40 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'vent', | ||||
|         'AppLayout', | ||||
|         'marionette', | ||||
|         'AddSeries/RootFolders/RootFolderLayout', | ||||
|         'AddSeries/Existing/AddExistingSeriesCollectionView', | ||||
|         'AddSeries/AddSeriesView', | ||||
|         'Profile/ProfileCollection', | ||||
|         'AddSeries/RootFolders/RootFolderCollection', | ||||
|         'Series/SeriesCollection' | ||||
|     ], function (vent, | ||||
|                  AppLayout, | ||||
|                  Marionette, | ||||
|                  RootFolderLayout, | ||||
|                  ExistingSeriesCollectionView, | ||||
|                  AddSeriesView, | ||||
|                  ProfileCollection, | ||||
|                  RootFolderCollection) { | ||||
| var vent = require('../vent'); | ||||
| var AppLayout = require('../AppLayout'); | ||||
| var Marionette = require('marionette'); | ||||
| var RootFolderLayout = require('./RootFolders/RootFolderLayout'); | ||||
| var ExistingSeriesCollectionView = require('./Existing/AddExistingSeriesCollectionView'); | ||||
| var AddSeriesView = require('./AddSeriesView'); | ||||
| var ProfileCollection = require('../Profile/ProfileCollection'); | ||||
| var RootFolderCollection = require('./RootFolders/RootFolderCollection'); | ||||
| require('../Series/SeriesCollection'); | ||||
|  | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'AddSeries/AddSeriesLayoutTemplate', | ||||
|  | ||||
|             regions: { | ||||
|                 workspace: '#add-series-workspace' | ||||
|             }, | ||||
|  | ||||
|             events: { | ||||
|                 'click .x-import': '_importSeries', | ||||
|                 'click .x-add-new': '_addSeries' | ||||
|             }, | ||||
|  | ||||
|             attributes: { | ||||
|                 id: 'add-series-screen' | ||||
|             }, | ||||
|  | ||||
|             initialize: function () { | ||||
|                 ProfileCollection.fetch(); | ||||
|                 RootFolderCollection.fetch() | ||||
|                     .done(function () { | ||||
|                         RootFolderCollection.synced = true; | ||||
|                     }); | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 this.workspace.show(new AddSeriesView()); | ||||
|             }, | ||||
|  | ||||
|             _folderSelected: function (options) { | ||||
|                 vent.trigger(vent.Commands.CloseModalCommand); | ||||
|  | ||||
|                 this.workspace.show(new ExistingSeriesCollectionView({model: options.model})); | ||||
|             }, | ||||
|  | ||||
|             _importSeries: function () { | ||||
|                 this.rootFolderLayout = new RootFolderLayout(); | ||||
|                 this.listenTo(this.rootFolderLayout, 'folderSelected', this._folderSelected); | ||||
|                 AppLayout.modalRegion.show(this.rootFolderLayout); | ||||
|             }, | ||||
|  | ||||
|             _addSeries: function () { | ||||
|                 this.workspace.show(new AddSeriesView()); | ||||
|             } | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template        : 'AddSeries/AddSeriesLayoutTemplate', | ||||
|     regions         : {workspace : '#add-series-workspace'}, | ||||
|     events          : { | ||||
|         'click .x-import'  : '_importSeries', | ||||
|         'click .x-add-new' : '_addSeries' | ||||
|     }, | ||||
|     attributes      : {id : 'add-series-screen'}, | ||||
|     initialize      : function(){ | ||||
|         ProfileCollection.fetch(); | ||||
|         RootFolderCollection.fetch().done(function(){ | ||||
|             RootFolderCollection.synced = true; | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     }, | ||||
|     onShow          : function(){ | ||||
|         this.workspace.show(new AddSeriesView()); | ||||
|     }, | ||||
|     _folderSelected : function(options){ | ||||
|         vent.trigger(vent.Commands.CloseModalCommand); | ||||
|         this.workspace.show(new ExistingSeriesCollectionView({model : options.model})); | ||||
|     }, | ||||
|     _importSeries   : function(){ | ||||
|         this.rootFolderLayout = new RootFolderLayout(); | ||||
|         this.listenTo(this.rootFolderLayout, 'folderSelected', this._folderSelected); | ||||
|         AppLayout.modalRegion.show(this.rootFolderLayout); | ||||
|     }, | ||||
|     _addSeries      : function(){ | ||||
|         this.workspace.show(new AddSeriesView()); | ||||
|     } | ||||
| }); | ||||
| @@ -1,174 +1,129 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'underscore', | ||||
|         'vent', | ||||
|         'marionette', | ||||
|         'AddSeries/AddSeriesCollection', | ||||
|         'AddSeries/SearchResultCollectionView', | ||||
|         'AddSeries/EmptyView', | ||||
|         'AddSeries/NotFoundView', | ||||
|         'AddSeries/ErrorView', | ||||
|         'Shared/LoadingView' | ||||
|     ], function (_, vent, Marionette, AddSeriesCollection, SearchResultCollectionView, EmptyView, NotFoundView, ErrorView, LoadingView) { | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'AddSeries/AddSeriesViewTemplate', | ||||
| var _ = require('underscore'); | ||||
| var vent = require('../vent'); | ||||
| var Marionette = require('marionette'); | ||||
| var AddSeriesCollection = require('./AddSeriesCollection'); | ||||
| var SearchResultCollectionView = require('./SearchResultCollectionView'); | ||||
| var EmptyView = require('./EmptyView'); | ||||
| var NotFoundView = require('./NotFoundView'); | ||||
| var ErrorView = require('./ErrorView'); | ||||
| var LoadingView = require('../Shared/LoadingView'); | ||||
|  | ||||
|             regions: { | ||||
|                 searchResult: '#search-result' | ||||
|             }, | ||||
|  | ||||
|             ui: { | ||||
|                 seriesSearch: '.x-series-search', | ||||
|                 searchBar   : '.x-search-bar', | ||||
|                 loadMore    : '.x-load-more' | ||||
|             }, | ||||
|  | ||||
|             events: { | ||||
|                 'click .x-load-more': '_onLoadMore' | ||||
|             }, | ||||
|  | ||||
|             initialize: function (options) { | ||||
|                 this.isExisting = options.isExisting; | ||||
|                 this.collection = new AddSeriesCollection(); | ||||
|  | ||||
|                 if (this.isExisting) { | ||||
|                     this.collection.unmappedFolderModel = this.model; | ||||
|                 } | ||||
|  | ||||
|                 if (this.isExisting) { | ||||
|                     this.className = 'existing-series'; | ||||
|                 } | ||||
|                 else { | ||||
|                     this.className = 'new-series'; | ||||
|                 } | ||||
|  | ||||
|                 this.listenTo(vent, vent.Events.SeriesAdded, this._onSeriesAdded); | ||||
|                 this.listenTo(this.collection, 'sync', this._showResults); | ||||
|  | ||||
|                 this.resultCollectionView = new SearchResultCollectionView({ | ||||
|                     collection: this.collection, | ||||
|                     isExisting: this.isExisting | ||||
|                 }); | ||||
|  | ||||
|                 this.throttledSearch = _.debounce(this.search, 1000, {trailing: true}).bind(this); | ||||
|             }, | ||||
|  | ||||
|             onRender: function () { | ||||
|                 var self = this; | ||||
|  | ||||
|                 this.$el.addClass(this.className); | ||||
|  | ||||
|                 this.ui.seriesSearch.keyup(function (e) { | ||||
|  | ||||
|                     //Ignore special keys: http://www.javascripter.net/faq/keycodes.htm | ||||
|                     if (_.contains([9, 16, 17, 18, 19, 20, 33, 34, 35, 36, 37, 38, 39, 40, 91, 92, 93 ], e.keyCode)) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     self._abortExistingSearch(); | ||||
|                     self.throttledSearch({ | ||||
|                         term: self.ui.seriesSearch.val() | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 this._clearResults(); | ||||
|  | ||||
|                 if (this.isExisting) { | ||||
|                     this.ui.searchBar.hide(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 this.ui.seriesSearch.focus(); | ||||
|             }, | ||||
|  | ||||
|             search: function (options) { | ||||
|                 var self = this; | ||||
|  | ||||
|                 this.collection.reset(); | ||||
|  | ||||
|                 if (!options.term || options.term === this.collection.term) { | ||||
|                     return Marionette.$.Deferred().resolve(); | ||||
|                 } | ||||
|  | ||||
|                 this.searchResult.show(new LoadingView()); | ||||
|                 this.collection.term = options.term; | ||||
|                 this.currentSearchPromise = this.collection.fetch({ | ||||
|                     data: { term: options.term } | ||||
|                 }); | ||||
|  | ||||
|                 this.currentSearchPromise.fail(function () { | ||||
|                     self._showError(); | ||||
|                 }); | ||||
|  | ||||
|                 return this.currentSearchPromise; | ||||
|             }, | ||||
|  | ||||
|             _onSeriesAdded: function (options) { | ||||
|                 if (this.isExisting && options.series.get('path') === this.model.get('folder').path) { | ||||
|                     this.close(); | ||||
|                 } | ||||
|  | ||||
|                 else if (!this.isExisting) { | ||||
|                     this.collection.term = ''; | ||||
|                     this.collection.reset(); | ||||
|                     this._clearResults(); | ||||
|                     this.ui.seriesSearch.val(''); | ||||
|                     this.ui.seriesSearch.focus(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             _onLoadMore: function () { | ||||
|                 var showingAll = this.resultCollectionView.showMore(); | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template             : 'AddSeries/AddSeriesViewTemplate', | ||||
|     regions              : {searchResult : '#search-result'}, | ||||
|     ui                   : { | ||||
|         seriesSearch : '.x-series-search', | ||||
|         searchBar    : '.x-search-bar', | ||||
|         loadMore     : '.x-load-more' | ||||
|     }, | ||||
|     events               : {"click .x-load-more" : '_onLoadMore'}, | ||||
|     initialize           : function(options){ | ||||
|         this.isExisting = options.isExisting; | ||||
|         this.collection = new AddSeriesCollection(); | ||||
|         if(this.isExisting) { | ||||
|             this.collection.unmappedFolderModel = this.model; | ||||
|         } | ||||
|         if(this.isExisting) { | ||||
|             this.className = 'existing-series'; | ||||
|         } | ||||
|         else { | ||||
|             this.className = 'new-series'; | ||||
|         } | ||||
|         this.listenTo(vent, vent.Events.SeriesAdded, this._onSeriesAdded); | ||||
|         this.listenTo(this.collection, 'sync', this._showResults); | ||||
|         this.resultCollectionView = new SearchResultCollectionView({ | ||||
|             collection : this.collection, | ||||
|             isExisting : this.isExisting | ||||
|         }); | ||||
|         this.throttledSearch = _.debounce(this.search, 1000, {trailing : true}).bind(this); | ||||
|     }, | ||||
|     onRender             : function(){ | ||||
|         var self = this; | ||||
|         this.$el.addClass(this.className); | ||||
|         this.ui.seriesSearch.keyup(function(e){ | ||||
|             if(_.contains([9, 16, 17, 18, 19, 20, 33, 34, 35, 36, 37, 38, 39, 40, 91, 92, 93], e.keyCode)) { | ||||
|                 return; | ||||
|             } | ||||
|             self._abortExistingSearch(); | ||||
|             self.throttledSearch({term : self.ui.seriesSearch.val()}); | ||||
|         }); | ||||
|         this._clearResults(); | ||||
|         if(this.isExisting) { | ||||
|             this.ui.searchBar.hide(); | ||||
|         } | ||||
|     }, | ||||
|     onShow               : function(){ | ||||
|         this.ui.seriesSearch.focus(); | ||||
|     }, | ||||
|     search               : function(options){ | ||||
|         var self = this; | ||||
|         this.collection.reset(); | ||||
|         if(!options.term || options.term === this.collection.term) { | ||||
|             return Marionette.$.Deferred().resolve(); | ||||
|         } | ||||
|         this.searchResult.show(new LoadingView()); | ||||
|         this.collection.term = options.term; | ||||
|         this.currentSearchPromise = this.collection.fetch({data : {term : options.term}}); | ||||
|         this.currentSearchPromise.fail(function(){ | ||||
|             self._showError(); | ||||
|         }); | ||||
|         return this.currentSearchPromise; | ||||
|     }, | ||||
|     _onSeriesAdded       : function(options){ | ||||
|         if(this.isExisting && options.series.get('path') === this.model.get('folder').path) { | ||||
|             this.close(); | ||||
|         } | ||||
|         else if(!this.isExisting) { | ||||
|             this.collection.term = ''; | ||||
|             this.collection.reset(); | ||||
|             this._clearResults(); | ||||
|             this.ui.seriesSearch.val(''); | ||||
|             this.ui.seriesSearch.focus(); | ||||
|         } | ||||
|     }, | ||||
|     _onLoadMore          : function(){ | ||||
|         var showingAll = this.resultCollectionView.showMore(); | ||||
|         this.ui.searchBar.show(); | ||||
|         if(showingAll) { | ||||
|             this.ui.loadMore.hide(); | ||||
|         } | ||||
|     }, | ||||
|     _clearResults        : function(){ | ||||
|         if(!this.isExisting) { | ||||
|             this.searchResult.show(new EmptyView()); | ||||
|         } | ||||
|         else { | ||||
|             this.searchResult.close(); | ||||
|         } | ||||
|     }, | ||||
|     _showResults         : function(){ | ||||
|         if(!this.isClosed) { | ||||
|             if(this.collection.length === 0) { | ||||
|                 this.ui.searchBar.show(); | ||||
|  | ||||
|                 if (showingAll) { | ||||
|                     this.ui.loadMore.hide(); | ||||
|                 } | ||||
|             }, | ||||
|              | ||||
|             _clearResults: function () { | ||||
|                 if (!this.isExisting) { | ||||
|                     this.searchResult.show(new EmptyView()); | ||||
|                 } | ||||
|                 else { | ||||
|                     this.searchResult.close(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             _showResults: function () { | ||||
|                 if (!this.isClosed) { | ||||
|  | ||||
|                     if (this.collection.length === 0) { | ||||
|                         this.ui.searchBar.show(); | ||||
|                         this.searchResult.show(new NotFoundView({term: this.collection.term})); | ||||
|                     } | ||||
|                     else { | ||||
|                         this.searchResult.show(this.resultCollectionView); | ||||
|                         if (!this.showingAll && this.isExisting) { | ||||
|                             this.ui.loadMore.show(); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             _abortExistingSearch: function () { | ||||
|                 if (this.currentSearchPromise && this.currentSearchPromise.readyState > 0 && this.currentSearchPromise.readyState < 4) { | ||||
|                     console.log('aborting previous pending search request.'); | ||||
|                     this.currentSearchPromise.abort(); | ||||
|                 } | ||||
|                 else { | ||||
|                     this._clearResults(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             _showError: function () { | ||||
|                 if (!this.isClosed) { | ||||
|                     this.ui.searchBar.show(); | ||||
|                     this.searchResult.show(new ErrorView({term: this.collection.term})); | ||||
|                     this.collection.term = ''; | ||||
|                 this.searchResult.show(new NotFoundView({term : this.collection.term})); | ||||
|             } | ||||
|             else { | ||||
|                 this.searchResult.show(this.resultCollectionView); | ||||
|                 if(!this.showingAll && this.isExisting) { | ||||
|                     this.ui.loadMore.show(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|         } | ||||
|     }, | ||||
|     _abortExistingSearch : function(){ | ||||
|         if(this.currentSearchPromise && this.currentSearchPromise.readyState > 0 && this.currentSearchPromise.readyState < 4) { | ||||
|             console.log('aborting previous pending search request.'); | ||||
|             this.currentSearchPromise.abort(); | ||||
|         } | ||||
|         else { | ||||
|             this._clearResults(); | ||||
|         } | ||||
|     }, | ||||
|     _showError           : function(){ | ||||
|         if(!this.isClosed) { | ||||
|             this.ui.searchBar.show(); | ||||
|             this.searchResult.show(new ErrorView({term : this.collection.term})); | ||||
|             this.collection.term = ''; | ||||
|         } | ||||
|     } | ||||
| }); | ||||
| @@ -1,11 +1,3 @@ | ||||
| 'use strict'; | ||||
| var Marionette = require('marionette'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'marionette' | ||||
|     ], function (Marionette) { | ||||
|  | ||||
|         return Marionette.CompositeView.extend({ | ||||
|             template: 'AddSeries/EmptyViewTemplate' | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.CompositeView.extend({template : 'AddSeries/EmptyViewTemplate'}); | ||||
| @@ -1,20 +1,11 @@ | ||||
| 'use strict'; | ||||
| var Marionette = require('marionette'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'marionette' | ||||
|     ], function (Marionette) { | ||||
|  | ||||
|         return Marionette.CompositeView.extend({ | ||||
|             template: 'AddSeries/ErrorViewTemplate', | ||||
|  | ||||
|             initialize: function (options) { | ||||
|                 this.options = options; | ||||
|             }, | ||||
|  | ||||
|             templateHelpers: function () { | ||||
|                 return  this.options; | ||||
|             } | ||||
|  | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.CompositeView.extend({ | ||||
|     template        : 'AddSeries/ErrorViewTemplate', | ||||
|     initialize      : function(options){ | ||||
|         this.options = options; | ||||
|     }, | ||||
|     templateHelpers : function(){ | ||||
|         return this.options; | ||||
|     } | ||||
| }); | ||||
| @@ -1,59 +1,38 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'AddSeries/AddSeriesView', | ||||
|         'AddSeries/Existing/UnmappedFolderCollection' | ||||
|     ], function (Marionette, AddSeriesView, UnmappedFolderCollection) { | ||||
| var Marionette = require('marionette'); | ||||
| var AddSeriesView = require('../AddSeriesView'); | ||||
| var UnmappedFolderCollection = require('./UnmappedFolderCollection'); | ||||
|  | ||||
|         return Marionette.CompositeView.extend({ | ||||
|  | ||||
|             itemView         : AddSeriesView, | ||||
|             itemViewContainer: '.x-loading-folders', | ||||
|             template         : 'AddSeries/Existing/AddExistingSeriesCollectionViewTemplate', | ||||
|  | ||||
|             ui: { | ||||
|                 loadingFolders: '.x-loading-folders' | ||||
|             }, | ||||
|  | ||||
|             initialize: function () { | ||||
|                 this.collection = new UnmappedFolderCollection(); | ||||
|                 this.collection.importItems(this.model); | ||||
|             }, | ||||
|  | ||||
|             showCollection: function () { | ||||
|                 this._showAndSearch(0); | ||||
|             }, | ||||
|  | ||||
|             appendHtml: function(collectionView, itemView, index){ | ||||
|                 collectionView.ui.loadingFolders.before(itemView.el); | ||||
|             }, | ||||
|  | ||||
|             _showAndSearch: function (index) { | ||||
|                 var self = this; | ||||
|                 var model = this.collection.at(index); | ||||
|  | ||||
|                 if (model) { | ||||
|                     var currentIndex = index; | ||||
|                     var folderName = model.get('folder').name; | ||||
|                     this.addItemView(model, this.getItemView(), index); | ||||
|                     this.children.findByModel(model) | ||||
|                         .search({term: folderName}) | ||||
|                         .always(function () { | ||||
|                             if (!self.isClosed) { | ||||
|                                 self._showAndSearch(currentIndex + 1); | ||||
|                             } | ||||
|                         }); | ||||
| module.exports = Marionette.CompositeView.extend({ | ||||
|     itemView          : AddSeriesView, | ||||
|     itemViewContainer : '.x-loading-folders', | ||||
|     template          : 'AddSeries/Existing/AddExistingSeriesCollectionViewTemplate', | ||||
|     ui                : {loadingFolders : '.x-loading-folders'}, | ||||
|     initialize        : function(){ | ||||
|         this.collection = new UnmappedFolderCollection(); | ||||
|         this.collection.importItems(this.model); | ||||
|     }, | ||||
|     showCollection    : function(){ | ||||
|         this._showAndSearch(0); | ||||
|     }, | ||||
|     appendHtml        : function(collectionView, itemView, index){ | ||||
|         collectionView.ui.loadingFolders.before(itemView.el); | ||||
|     }, | ||||
|     _showAndSearch    : function(index){ | ||||
|         var self = this; | ||||
|         var model = this.collection.at(index); | ||||
|         if(model) { | ||||
|             var currentIndex = index; | ||||
|             var folderName = model.get('folder').name; | ||||
|             this.addItemView(model, this.getItemView(), index); | ||||
|             this.children.findByModel(model).search({term : folderName}).always(function(){ | ||||
|                 if(!self.isClosed) { | ||||
|                     self._showAndSearch(currentIndex + 1); | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     this.ui.loadingFolders.hide(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             itemViewOptions: { | ||||
|                 isExisting: true | ||||
|             } | ||||
|  | ||||
|         }); | ||||
|     }); | ||||
|             }); | ||||
|         } | ||||
|         else { | ||||
|             this.ui.loadingFolders.hide(); | ||||
|         } | ||||
|     }, | ||||
|     itemViewOptions   : {isExisting : true} | ||||
| }); | ||||
| @@ -1,24 +1,17 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backbone', | ||||
|         'AddSeries/Existing/UnmappedFolderModel', | ||||
|         'underscore' | ||||
|     ], function (Backbone, UnmappedFolderModel,_) { | ||||
|         return Backbone.Collection.extend({ | ||||
|             model: UnmappedFolderModel, | ||||
| var Backbone = require('backbone'); | ||||
| var UnmappedFolderModel = require('./UnmappedFolderModel'); | ||||
| var _ = require('underscore'); | ||||
|  | ||||
|             importItems: function (rootFolderModel) { | ||||
|  | ||||
|                 this.reset(); | ||||
|                 var rootFolder = rootFolderModel; | ||||
|  | ||||
|                 _.each(rootFolderModel.get('unmappedFolders'), function (folder) { | ||||
|                     this.push(new UnmappedFolderModel({ | ||||
|                         rootFolder: rootFolder, | ||||
|                         folder    : folder | ||||
|                     })); | ||||
|                 }, this); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Backbone.Collection.extend({ | ||||
|     model       : UnmappedFolderModel, | ||||
|     importItems : function(rootFolderModel){ | ||||
|         this.reset(); | ||||
|         var rootFolder = rootFolderModel; | ||||
|         _.each(rootFolderModel.get('unmappedFolders'), function(folder){ | ||||
|             this.push(new UnmappedFolderModel({ | ||||
|                 rootFolder : rootFolder, | ||||
|                 folder     : folder | ||||
|             })); | ||||
|         }, this); | ||||
|     } | ||||
| }); | ||||
| @@ -1,10 +1,3 @@ | ||||
| 'use strict'; | ||||
| var Backbone = require('backbone'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'backbone' | ||||
|     ], function (Backbone) { | ||||
|         return Backbone.Model.extend({ | ||||
|  | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Backbone.Model.extend({}); | ||||
| @@ -1,20 +1,11 @@ | ||||
| 'use strict'; | ||||
| var Marionette = require('marionette'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'marionette' | ||||
|     ], function (Marionette) { | ||||
|  | ||||
|         return Marionette.CompositeView.extend({ | ||||
|             template: 'AddSeries/NotFoundViewTemplate', | ||||
|  | ||||
|             initialize: function (options) { | ||||
|                 this.options = options; | ||||
|             }, | ||||
|  | ||||
|             templateHelpers: function () { | ||||
|                 return  this.options; | ||||
|             } | ||||
|  | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.CompositeView.extend({ | ||||
|     template        : 'AddSeries/NotFoundViewTemplate', | ||||
|     initialize      : function(options){ | ||||
|         this.options = options; | ||||
|     }, | ||||
|     templateHelpers : function(){ | ||||
|         return this.options; | ||||
|     } | ||||
| }); | ||||
| @@ -1,17 +1,11 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backbone', | ||||
|         'AddSeries/RootFolders/RootFolderModel', | ||||
|         'Mixins/backbone.signalr.mixin' | ||||
|     ], function (Backbone, RootFolderModel) { | ||||
| var Backbone = require('backbone'); | ||||
| var RootFolderModel = require('./RootFolderModel'); | ||||
| require('../../Mixins/backbone.signalr.mixin'); | ||||
|  | ||||
|         var RootFolderCollection = Backbone.Collection.extend({ | ||||
|             url  : window.NzbDrone.ApiRoot + '/rootfolder', | ||||
|             model: RootFolderModel | ||||
|         }); | ||||
|  | ||||
|         //var collection = new RootFolderCollection().bindSignalR(); | ||||
|  | ||||
|         return new RootFolderCollection(); | ||||
| module.exports = (function(){ | ||||
|     var RootFolderCollection = Backbone.Collection.extend({ | ||||
|         url   : window.NzbDrone.ApiRoot + '/rootfolder', | ||||
|         model : RootFolderModel | ||||
|     }); | ||||
|     return new RootFolderCollection(); | ||||
| }).call(this); | ||||
| @@ -1,15 +1,8 @@ | ||||
| 'use strict'; | ||||
| var Marionette = require('marionette'); | ||||
| var RootFolderItemView = require('./RootFolderItemView'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'AddSeries/RootFolders/RootFolderItemView' | ||||
|     ], function (Marionette, RootFolderItemView) { | ||||
|  | ||||
|  | ||||
|         return Marionette.CompositeView.extend({ | ||||
|             template          : 'AddSeries/RootFolders/RootFolderCollectionViewTemplate', | ||||
|             itemViewContainer : '.x-root-folders', | ||||
|             itemView          : RootFolderItemView | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.CompositeView.extend({ | ||||
|     template          : 'AddSeries/RootFolders/RootFolderCollectionViewTemplate', | ||||
|     itemViewContainer : '.x-root-folders', | ||||
|     itemView          : RootFolderItemView | ||||
| }); | ||||
| @@ -1,37 +1,22 @@ | ||||
| 'use strict'; | ||||
| var Marionette = require('marionette'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'marionette' | ||||
|     ], function (Marionette) { | ||||
|  | ||||
|         return Marionette.ItemView.extend({ | ||||
|  | ||||
|             template: 'AddSeries/RootFolders/RootFolderItemViewTemplate', | ||||
|             tagName : 'tr', | ||||
|  | ||||
|             initialize: function () { | ||||
|                  this.listenTo(this.model, 'change', this.render); | ||||
|             }, | ||||
|  | ||||
|  | ||||
|             events: { | ||||
|                 'click .x-delete': 'removeFolder', | ||||
|                 'click .x-folder': 'folderSelected' | ||||
|             }, | ||||
|  | ||||
|             removeFolder: function () { | ||||
|  | ||||
|                 var self = this; | ||||
|  | ||||
|                 this.model.destroy() | ||||
|                     .success(function(){ | ||||
|                         self.close(); | ||||
|                     }); | ||||
|             }, | ||||
|  | ||||
|             folderSelected: function () { | ||||
|                 this.trigger('folderSelected', this.model); | ||||
|             } | ||||
| module.exports = Marionette.ItemView.extend({ | ||||
|     template       : 'AddSeries/RootFolders/RootFolderItemViewTemplate', | ||||
|     tagName        : 'tr', | ||||
|     initialize     : function(){ | ||||
|         this.listenTo(this.model, 'change', this.render); | ||||
|     }, | ||||
|     events         : { | ||||
|         'click .x-delete' : 'removeFolder', | ||||
|         'click .x-folder' : 'folderSelected' | ||||
|     }, | ||||
|     removeFolder   : function(){ | ||||
|         var self = this; | ||||
|         this.model.destroy().success(function(){ | ||||
|             self.close(); | ||||
|         }); | ||||
|     }); | ||||
|     }, | ||||
|     folderSelected : function(){ | ||||
|         this.trigger('folderSelected', this.model); | ||||
|     } | ||||
| }); | ||||
| @@ -1,81 +1,54 @@ | ||||
| 'use strict'; | ||||
| var Marionette = require('marionette'); | ||||
| var RootFolderCollectionView = require('./RootFolderCollectionView'); | ||||
| var RootFolderCollection = require('./RootFolderCollection'); | ||||
| var RootFolderModel = require('./RootFolderModel'); | ||||
| var LoadingView = require('../../Shared/LoadingView'); | ||||
| var AsValidatedView = require('../../Mixins/AsValidatedView'); | ||||
| require('../../Mixins/FileBrowser'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'AddSeries/RootFolders/RootFolderCollectionView', | ||||
|         'AddSeries/RootFolders/RootFolderCollection', | ||||
|         'AddSeries/RootFolders/RootFolderModel', | ||||
|         'Shared/LoadingView', | ||||
|         'Mixins/AsValidatedView', | ||||
|         'Mixins/FileBrowser' | ||||
|     ], function (Marionette, RootFolderCollectionView, RootFolderCollection, RootFolderModel, LoadingView, AsValidatedView) { | ||||
|  | ||||
|         var layout = Marionette.Layout.extend({ | ||||
|             template: 'AddSeries/RootFolders/RootFolderLayoutTemplate', | ||||
|  | ||||
|             ui: { | ||||
|                 pathInput: '.x-path' | ||||
|             }, | ||||
|  | ||||
|             regions: { | ||||
|                 currentDirs: '#current-dirs' | ||||
|             }, | ||||
|  | ||||
|             events: { | ||||
|                 'click .x-add': '_addFolder', | ||||
|                 'keydown .x-path input': '_keydown' | ||||
|             }, | ||||
|  | ||||
|             initialize: function () { | ||||
|                 this.collection = RootFolderCollection; | ||||
|                 this.rootfolderListView = new RootFolderCollectionView({ collection: RootFolderCollection }); | ||||
|  | ||||
|                 this.listenTo(this.rootfolderListView, 'itemview:folderSelected', this._onFolderSelected); | ||||
|                 this.listenTo(RootFolderCollection, 'sync', this._showCurrentDirs); | ||||
|             }, | ||||
|  | ||||
|             onRender: function () { | ||||
|                 this.currentDirs.show(new LoadingView()); | ||||
|  | ||||
|                 if (RootFolderCollection.synced) { | ||||
|                     this._showCurrentDirs(); | ||||
|                 } | ||||
|  | ||||
|                 this.ui.pathInput.fileBrowser(); | ||||
|             }, | ||||
|  | ||||
|             _onFolderSelected: function (options) { | ||||
|                 this.trigger('folderSelected', options); | ||||
|             }, | ||||
|  | ||||
|             _addFolder: function () { | ||||
|                 var self = this; | ||||
|  | ||||
|                 var newDir = new RootFolderModel({ | ||||
|                     Path: this.ui.pathInput.val() | ||||
|                 }); | ||||
|  | ||||
|                 this.bindToModelValidation(newDir); | ||||
|  | ||||
|                 newDir.save().done(function () { | ||||
|                     RootFolderCollection.add(newDir); | ||||
|                     self.trigger('folderSelected', {model: newDir}); | ||||
|                 }); | ||||
|             }, | ||||
|  | ||||
|             _showCurrentDirs: function () { | ||||
|                 this.currentDirs.show(this.rootfolderListView); | ||||
|             }, | ||||
|  | ||||
|             _keydown: function (e) { | ||||
|                 if (e.keyCode !== 13) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 this._addFolder(); | ||||
| module.exports = (function(){ | ||||
|     var layout = Marionette.Layout.extend({ | ||||
|         template          : 'AddSeries/RootFolders/RootFolderLayoutTemplate', | ||||
|         ui                : {pathInput : '.x-path'}, | ||||
|         regions           : {currentDirs : '#current-dirs'}, | ||||
|         events            : { | ||||
|             'click .x-add'          : '_addFolder', | ||||
|             'keydown .x-path input' : '_keydown' | ||||
|         }, | ||||
|         initialize        : function(){ | ||||
|             this.collection = RootFolderCollection; | ||||
|             this.rootfolderListView = new RootFolderCollectionView({collection : RootFolderCollection}); | ||||
|             this.listenTo(this.rootfolderListView, 'itemview:folderSelected', this._onFolderSelected); | ||||
|             this.listenTo(RootFolderCollection, 'sync', this._showCurrentDirs); | ||||
|         }, | ||||
|         onRender          : function(){ | ||||
|             this.currentDirs.show(new LoadingView()); | ||||
|             if(RootFolderCollection.synced) { | ||||
|                 this._showCurrentDirs(); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         return AsValidatedView.apply(layout); | ||||
|             this.ui.pathInput.fileBrowser(); | ||||
|         }, | ||||
|         _onFolderSelected : function(options){ | ||||
|             this.trigger('folderSelected', options); | ||||
|         }, | ||||
|         _addFolder        : function(){ | ||||
|             var self = this; | ||||
|             var newDir = new RootFolderModel({Path : this.ui.pathInput.val()}); | ||||
|             this.bindToModelValidation(newDir); | ||||
|             newDir.save().done(function(){ | ||||
|                 RootFolderCollection.add(newDir); | ||||
|                 self.trigger('folderSelected', {model : newDir}); | ||||
|             }); | ||||
|         }, | ||||
|         _showCurrentDirs  : function(){ | ||||
|             this.currentDirs.show(this.rootfolderListView); | ||||
|         }, | ||||
|         _keydown          : function(e){ | ||||
|             if(e.keyCode !== 13) { | ||||
|                 return; | ||||
|             } | ||||
|             this._addFolder(); | ||||
|         } | ||||
|     }); | ||||
|     return AsValidatedView.apply(layout); | ||||
| }).call(this); | ||||
| @@ -1,12 +1,6 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backbone' | ||||
|     ], function (Backbone) { | ||||
|         return Backbone.Model.extend({ | ||||
|             urlRoot : window.NzbDrone.ApiRoot + '/rootfolder', | ||||
|             defaults: { | ||||
|                 freeSpace: 0 | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| var Backbone = require('backbone'); | ||||
|  | ||||
| module.exports = Backbone.Model.extend({ | ||||
|     urlRoot  : window.NzbDrone.ApiRoot + '/rootfolder', | ||||
|     defaults : {freeSpace : 0} | ||||
| }); | ||||
| @@ -1,35 +1,24 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'AddSeries/SearchResultView' | ||||
|     ], function (Marionette, SearchResultView) { | ||||
| var Marionette = require('marionette'); | ||||
| var SearchResultView = require('./SearchResultView'); | ||||
|  | ||||
|         return Marionette.CollectionView.extend({ | ||||
|  | ||||
|             itemView: SearchResultView, | ||||
|  | ||||
|             initialize: function (options) { | ||||
|                 this.isExisting = options.isExisting; | ||||
|                 this.showing = 1; | ||||
|             }, | ||||
|  | ||||
|             showAll: function () { | ||||
|                 this.showingAll = true; | ||||
|                 this.render(); | ||||
|             }, | ||||
|  | ||||
|             showMore: function () { | ||||
|                 this.showing += 5; | ||||
|                 this.render(); | ||||
|  | ||||
|                 return this.showing >= this.collection.length; | ||||
|             }, | ||||
|  | ||||
|             appendHtml: function (collectionView, itemView, index) { | ||||
|                 if (!this.isExisting || index < this.showing || index === 0) { | ||||
|                     collectionView.$el.append(itemView.el); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.CollectionView.extend({ | ||||
|     itemView   : SearchResultView, | ||||
|     initialize : function(options){ | ||||
|         this.isExisting = options.isExisting; | ||||
|         this.showing = 1; | ||||
|     }, | ||||
|     showAll    : function(){ | ||||
|         this.showingAll = true; | ||||
|         this.render(); | ||||
|     }, | ||||
|     showMore   : function(){ | ||||
|         this.showing += 5; | ||||
|         this.render(); | ||||
|         return this.showing >= this.collection.length; | ||||
|     }, | ||||
|     appendHtml : function(collectionView, itemView, index){ | ||||
|         if(!this.isExisting || index < this.showing || index === 0) { | ||||
|             collectionView.$el.append(itemView.el); | ||||
|         } | ||||
|     } | ||||
| }); | ||||
| @@ -1,27 +1,22 @@ | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'Shared/Modal/ModalRegion', | ||||
|         'Shared/FileBrowser/FileBrowserModalRegion', | ||||
|         'Shared/ControlPanel/ControlPanelRegion' | ||||
|     ], function (Marionette, ModalRegion, FileBrowserModalRegion, ControlPanelRegion) { | ||||
|         'use strict'; | ||||
| var Marionette = require('marionette'); | ||||
| var ModalRegion = require('./Shared/Modal/ModalRegion'); | ||||
| var FileBrowserModalRegion = require('./Shared/FileBrowser/FileBrowserModalRegion'); | ||||
| var ControlPanelRegion = require('./Shared/ControlPanel/ControlPanelRegion'); | ||||
|  | ||||
|         var Layout = Marionette.Layout.extend({ | ||||
|  | ||||
|             regions: { | ||||
|                 navbarRegion      : '#nav-region', | ||||
|                 mainRegion        : '#main-region' | ||||
|             }, | ||||
|  | ||||
|             initialize: function () { | ||||
|                 this.addRegions({ | ||||
|                     modalRegion            : ModalRegion, | ||||
|                     fileBrowserModalRegion : FileBrowserModalRegion, | ||||
|                     controlPanelRegion     : ControlPanelRegion | ||||
|                 }); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         return new Layout({el: 'body'}); | ||||
| module.exports = (function(){ | ||||
|     'use strict'; | ||||
|     var Layout = Marionette.Layout.extend({ | ||||
|         regions    : { | ||||
|             navbarRegion : '#nav-region', | ||||
|             mainRegion   : '#main-region' | ||||
|         }, | ||||
|         initialize : function(){ | ||||
|             this.addRegions({ | ||||
|                 modalRegion            : ModalRegion, | ||||
|                 fileBrowserModalRegion : FileBrowserModalRegion, | ||||
|                 controlPanelRegion     : ControlPanelRegion | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
|     return new Layout({el : 'body'}); | ||||
| }).call(this); | ||||
| @@ -1,25 +1,18 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'System/StatusModel', | ||||
|         'Mixins/CopyToClipboard' | ||||
|     ], function (Marionette, StatusModel) { | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'Calendar/CalendarFeedViewTemplate', | ||||
| var Marionette = require('marionette'); | ||||
| var StatusModel = require('../System/StatusModel'); | ||||
| require('../Mixins/CopyToClipboard'); | ||||
|  | ||||
|             ui: { | ||||
|                 icalUrl       : '.x-ical-url', | ||||
|                 icalCopy      : '.x-ical-copy' | ||||
|             }, | ||||
|  | ||||
|             templateHelpers: { | ||||
|                 icalHttpUrl   : window.location.protocol + '//' + window.location.host + StatusModel.get('urlBase') + '/feed/calendar/NzbDrone.ics?apikey=' + window.NzbDrone.ApiKey, | ||||
|                 icalWebCalUrl : 'webcal://' + window.location.host + StatusModel.get('urlBase') + '/feed/calendar/NzbDrone.ics?apikey=' + window.NzbDrone.ApiKey | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 this.ui.icalCopy.copyToClipboard(this.ui.icalUrl); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template        : 'Calendar/CalendarFeedViewTemplate', | ||||
|     ui              : { | ||||
|         icalUrl  : '.x-ical-url', | ||||
|         icalCopy : '.x-ical-copy' | ||||
|     }, | ||||
|     templateHelpers : { | ||||
|         icalHttpUrl   : window.location.protocol + '//' + window.location.host + StatusModel.get('urlBase') + '/feed/calendar/NzbDrone.ics?apikey=' + window.NzbDrone.ApiKey, | ||||
|         icalWebCalUrl : 'webcal://' + window.location.host + StatusModel.get('urlBase') + '/feed/calendar/NzbDrone.ics?apikey=' + window.NzbDrone.ApiKey | ||||
|     }, | ||||
|     onShow          : function(){ | ||||
|         this.ui.icalCopy.copyToClipboard(this.ui.icalUrl); | ||||
|     } | ||||
| }); | ||||
| @@ -1,40 +1,28 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'AppLayout', | ||||
|         'marionette', | ||||
|         'Calendar/UpcomingCollectionView', | ||||
|         'Calendar/CalendarView', | ||||
|         'Calendar/CalendarFeedView' | ||||
|     ], function (AppLayout, Marionette, UpcomingCollectionView, CalendarView, CalendarFeedView) { | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'Calendar/CalendarLayoutTemplate', | ||||
| var AppLayout = require('../AppLayout'); | ||||
| var Marionette = require('marionette'); | ||||
| var UpcomingCollectionView = require('./UpcomingCollectionView'); | ||||
| var CalendarView = require('./CalendarView'); | ||||
| var CalendarFeedView = require('./CalendarFeedView'); | ||||
|  | ||||
|             regions: { | ||||
|                 upcoming: '#x-upcoming', | ||||
|                 calendar: '#x-calendar' | ||||
|             }, | ||||
|              | ||||
|             events: { | ||||
|                 'click .x-ical': '_showiCal' | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 this._showUpcoming(); | ||||
|                 this._showCalendar(); | ||||
|             }, | ||||
|  | ||||
|             _showUpcoming: function () { | ||||
|                 this.upcoming.show(new UpcomingCollectionView()); | ||||
|             }, | ||||
|  | ||||
|             _showCalendar: function () { | ||||
|                 this.calendar.show(new CalendarView()); | ||||
|             }, | ||||
|              | ||||
|             _showiCal: function () { | ||||
|                 var view = new CalendarFeedView(); | ||||
|                 AppLayout.modalRegion.show(view); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template      : 'Calendar/CalendarLayoutTemplate', | ||||
|     regions       : { | ||||
|         upcoming : '#x-upcoming', | ||||
|         calendar : '#x-calendar' | ||||
|     }, | ||||
|     events        : {"click .x-ical" : '_showiCal'}, | ||||
|     onShow        : function(){ | ||||
|         this._showUpcoming(); | ||||
|         this._showCalendar(); | ||||
|     }, | ||||
|     _showUpcoming : function(){ | ||||
|         this.upcoming.show(new UpcomingCollectionView()); | ||||
|     }, | ||||
|     _showCalendar : function(){ | ||||
|         this.calendar.show(new CalendarView()); | ||||
|     }, | ||||
|     _showiCal     : function(){ | ||||
|         var view = new CalendarFeedView(); | ||||
|         AppLayout.modalRegion.show(view); | ||||
|     } | ||||
| }); | ||||
| @@ -1,250 +1,195 @@ | ||||
| 'use strict'; | ||||
| var $ = require('jquery'); | ||||
| var vent = require('../vent'); | ||||
| var Marionette = require('marionette'); | ||||
| var moment = require('moment'); | ||||
| var CalendarCollection = require('./Collection'); | ||||
| var UiSettings = require('../Shared/UiSettingsModel'); | ||||
| var QueueCollection = require('../Activity/Queue/QueueCollection'); | ||||
| var Config = require('../Config'); | ||||
| require('../Mixins/backbone.signalr.mixin'); | ||||
| require('fullcalendar'); | ||||
| require('jquery.easypiechart'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'jquery', | ||||
|         'vent', | ||||
|         'marionette', | ||||
|         'moment', | ||||
|         'Calendar/Collection', | ||||
|         'Shared/UiSettingsModel', | ||||
|         'Activity/Queue/QueueCollection', | ||||
|         'Config', | ||||
|         'Mixins/backbone.signalr.mixin', | ||||
|         'fullcalendar', | ||||
|         'jquery.easypiechart' | ||||
|     ], function ($, vent, Marionette, moment, CalendarCollection, UiSettings, QueueCollection, Config) { | ||||
|  | ||||
|         return Marionette.ItemView.extend({ | ||||
|             storageKey: 'calendar.view', | ||||
|  | ||||
|             initialize: function () { | ||||
|                 this.collection = new CalendarCollection().bindSignalR({ updateOnly: true }); | ||||
|                 this.listenTo(this.collection, 'change', this._reloadCalendarEvents); | ||||
|                 this.listenTo(QueueCollection, 'sync', this._reloadCalendarEvents); | ||||
|             }, | ||||
|  | ||||
|             render    : function () { | ||||
|                 this.$el.empty().fullCalendar(this._getOptions()); | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 this.$('.fc-button-today').click(); | ||||
|             }, | ||||
|  | ||||
|             _viewRender: function (view) { | ||||
|  | ||||
|                 if ($(window).width() < 768) { | ||||
|                     this.$('.fc-header-title').show(); | ||||
|                     this.$('.calendar-title').remove(); | ||||
|  | ||||
|                     var title = this.$('.fc-header-title').text(); | ||||
|                     var titleDiv = '<div class="calendar-title"><h2>{0}</h2></div>'.format(title); | ||||
|  | ||||
|                     this.$('.fc-header').before(titleDiv); | ||||
|                     this.$('.fc-header-title').hide(); | ||||
| module.exports = Marionette.ItemView.extend({ | ||||
|     storageKey            : 'calendar.view', | ||||
|     initialize            : function(){ | ||||
|         this.collection = new CalendarCollection().bindSignalR({updateOnly : true}); | ||||
|         this.listenTo(this.collection, 'change', this._reloadCalendarEvents); | ||||
|         this.listenTo(QueueCollection, 'sync', this._reloadCalendarEvents); | ||||
|     }, | ||||
|     render                : function(){ | ||||
|         this.$el.empty().fullCalendar(this._getOptions()); | ||||
|     }, | ||||
|     onShow                : function(){ | ||||
|         this.$('.fc-button-today').click(); | ||||
|     }, | ||||
|     _viewRender           : function(view){ | ||||
|         if($(window).width() < 768) { | ||||
|             this.$('.fc-header-title').show(); | ||||
|             this.$('.calendar-title').remove(); | ||||
|             var title = this.$('.fc-header-title').text(); | ||||
|             var titleDiv = '<div class="calendar-title"><h2>{0}</h2></div>'.format(title); | ||||
|             this.$('.fc-header').before(titleDiv); | ||||
|             this.$('.fc-header-title').hide(); | ||||
|         } | ||||
|         if(Config.getValue(this.storageKey) !== view.name) { | ||||
|             Config.setValue(this.storageKey, view.name); | ||||
|         } | ||||
|         this._getEvents(view); | ||||
|     }, | ||||
|     _eventRender          : function(event, element){ | ||||
|         this.$(element).addClass(event.statusLevel); | ||||
|         this.$(element).children('.fc-event-inner').addClass(event.statusLevel); | ||||
|         if(event.downloading) { | ||||
|             var progress = 100 - event.downloading.get('sizeleft') / event.downloading.get('size') * 100; | ||||
|             var releaseTitle = event.downloading.get('title'); | ||||
|             var estimatedCompletionTime = moment(event.downloading.get('estimatedCompletionTime')).fromNow(); | ||||
|             var status = event.downloading.get('status').toLocaleLowerCase(); | ||||
|             var errorMessage = event.downloading.get('errorMessage'); | ||||
|             if(status === 'pending') { | ||||
|                 this._addStatusIcon(element, 'icon-time', 'Release will be processed {0}'.format(estimatedCompletionTime)); | ||||
|             } | ||||
|             else if(errorMessage) { | ||||
|                 if(status === 'completed') { | ||||
|                     this._addStatusIcon(element, 'icon-nd-import-failed', 'Import failed: {0}'.format(errorMessage)); | ||||
|                 } | ||||
|  | ||||
|                 if (Config.getValue(this.storageKey) !== view.name) { | ||||
|                     Config.setValue(this.storageKey, view.name); | ||||
|                 } | ||||
|                  | ||||
|                 this._getEvents(view); | ||||
|             }, | ||||
|              | ||||
|             _eventRender: function (event, element) { | ||||
|                 this.$(element).addClass(event.statusLevel); | ||||
|                 this.$(element).children('.fc-event-inner').addClass(event.statusLevel); | ||||
|  | ||||
|                 if (event.downloading) { | ||||
|                     var progress = 100 - (event.downloading.get('sizeleft') / event.downloading.get('size') * 100); | ||||
|                     var releaseTitle = event.downloading.get('title'); | ||||
|                     var estimatedCompletionTime = moment(event.downloading.get('estimatedCompletionTime')).fromNow(); | ||||
|                     var status = event.downloading.get('status').toLocaleLowerCase(); | ||||
|                     var errorMessage = event.downloading.get('errorMessage'); | ||||
|  | ||||
|                     if (status === 'pending') { | ||||
|                         this._addStatusIcon(element, 'icon-time', 'Release will be processed {0}'.format(estimatedCompletionTime)); | ||||
|                     } | ||||
|  | ||||
|                     else if (errorMessage) { | ||||
|                         if (status === 'completed') { | ||||
|                             this._addStatusIcon(element, 'icon-nd-import-failed', 'Import failed: {0}'.format(errorMessage)); | ||||
|                         } | ||||
|                         else { | ||||
|                             this._addStatusIcon(element, 'icon-nd-download-failed', 'Download failed: {0}'.format(errorMessage)); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     else if (status === 'failed') { | ||||
|                         this._addStatusIcon(element, 'icon-nd-download-failed', 'Download failed: check download client for more details'); | ||||
|                     } | ||||
|  | ||||
|                     else if (status === 'warning') { | ||||
|                         this._addStatusIcon(element, 'icon-nd-download-warning', 'Download warning: check download client for more details'); | ||||
|                     } | ||||
|  | ||||
|                     else { | ||||
|                         this.$(element).find('.fc-event-time') | ||||
|                             .after('<span class="chart pull-right" data-percent="{0}"></span>'.format(progress)); | ||||
|  | ||||
|                         this.$(element).find('.chart').easyPieChart({ | ||||
|                             barColor  : '#ffffff', | ||||
|                             trackColor: false, | ||||
|                             scaleColor: false, | ||||
|                             lineWidth : 2, | ||||
|                             size      : 14, | ||||
|                             animate   : false | ||||
|                         }); | ||||
|  | ||||
|                         this.$(element).find('.chart').tooltip({ | ||||
|                             title: 'Episode is downloading - {0}% {1}'.format(progress.toFixed(1), releaseTitle), | ||||
|                             container: '.fc-content' | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|              | ||||
|             _getEvents: function (view) { | ||||
|                 var start = view.start.toISOString(); | ||||
|                 var end = view.end.toISOString(); | ||||
|  | ||||
|                 this.$el.fullCalendar('removeEvents'); | ||||
|  | ||||
|                 this.collection.fetch({ | ||||
|                     data   : { start: start, end: end }, | ||||
|                     success: this._setEventData.bind(this) | ||||
|                 }); | ||||
|             }, | ||||
|  | ||||
|             _setEventData: function (collection) { | ||||
|                 var events = []; | ||||
|  | ||||
|                 var self = this; | ||||
|  | ||||
|                 collection.each(function (model) { | ||||
|                     var seriesTitle = model.get('series').title; | ||||
|                     var start = model.get('airDateUtc'); | ||||
|                     var runtime = model.get('series').runtime; | ||||
|                     var end = moment(start).add('minutes', runtime).toISOString(); | ||||
|  | ||||
|                     var event = { | ||||
|                         title       : seriesTitle, | ||||
|                         start       : moment(start), | ||||
|                         end         : moment(end), | ||||
|                         allDay      : false, | ||||
|                         statusLevel : self._getStatusLevel(model, end), | ||||
|                         downloading : QueueCollection.findEpisode(model.get('id')), | ||||
|                         model       : model | ||||
|                     }; | ||||
|  | ||||
|                     events.push(event); | ||||
|                 }); | ||||
|  | ||||
|                 this.$el.fullCalendar('addEventSource', events); | ||||
|             }, | ||||
|  | ||||
|             _getStatusLevel: function (element, endTime) { | ||||
|                 var hasFile = element.get('hasFile'); | ||||
|                 var downloading = QueueCollection.findEpisode(element.get('id')) || element.get('grabbed'); | ||||
|                 var currentTime = moment(); | ||||
|                 var start = moment(element.get('airDateUtc')); | ||||
|                 var end = moment(endTime); | ||||
|  | ||||
|                 var statusLevel = 'primary'; | ||||
|  | ||||
|                 if (hasFile) { | ||||
|                     statusLevel = 'success'; | ||||
|                 } | ||||
|  | ||||
|                 else if (downloading) { | ||||
|                     statusLevel = 'purple'; | ||||
|                 } | ||||
|  | ||||
|                 else if (currentTime.isAfter(start) && currentTime.isBefore(end)) { | ||||
|                     statusLevel = 'warning'; | ||||
|                 } | ||||
|  | ||||
|                 else if (start.isBefore(currentTime) && !hasFile) { | ||||
|                     statusLevel = 'danger'; | ||||
|                 } | ||||
|  | ||||
|                 else if (element.get('episodeNumber') === 1) { | ||||
|                     statusLevel = 'premiere'; | ||||
|                 } | ||||
|  | ||||
|                 if (end.isBefore(currentTime.startOf('day'))) { | ||||
|                     statusLevel += ' past'; | ||||
|                 } | ||||
|  | ||||
|                 return statusLevel; | ||||
|             }, | ||||
|  | ||||
|             _reloadCalendarEvents: function () { | ||||
|                 this.$el.fullCalendar('removeEvents'); | ||||
|                 this._setEventData(this.collection); | ||||
|             }, | ||||
|  | ||||
|             _getOptions: function () { | ||||
|                 var options = { | ||||
|                     allDayDefault : false, | ||||
|                     weekMode      : 'variable', | ||||
|                     firstDay      : UiSettings.get('firstDayOfWeek'), | ||||
|                     timeFormat    : 'h(:mm)a', | ||||
|                     viewRender    : this._viewRender.bind(this), | ||||
|                     eventRender   : this._eventRender.bind(this), | ||||
|                     eventClick    : function (event) { | ||||
|                         vent.trigger(vent.Commands.ShowEpisodeDetails, {episode: event.model}); | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 if ($(window).width() < 768) { | ||||
|                     options.defaultView = Config.getValue(this.storageKey, 'basicDay'); | ||||
|  | ||||
|                     options.header = { | ||||
|                         left  : 'prev,next today', | ||||
|                         center: 'title', | ||||
|                         right : 'basicWeek,basicDay' | ||||
|                     }; | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     options.defaultView = Config.getValue(this.storageKey, 'basicWeek'); | ||||
|  | ||||
|                     options.header = { | ||||
|                         left  : 'prev,next today', | ||||
|                         center: 'title', | ||||
|                         right : 'month,basicWeek,basicDay' | ||||
|                     }; | ||||
|                     this._addStatusIcon(element, 'icon-nd-download-failed', 'Download failed: {0}'.format(errorMessage)); | ||||
|                 } | ||||
|  | ||||
|                 options.titleFormat = { | ||||
|                     month : 'MMMM YYYY', | ||||
|                     week  : UiSettings.get('shortDateFormat'), | ||||
|                     day   : UiSettings.get('longDateFormat') | ||||
|                 }; | ||||
|  | ||||
|                 options.columnFormat = { | ||||
|                     month : 'ddd',    // Mon | ||||
|                     week  : UiSettings.get('calendarWeekColumnHeader'), | ||||
|                     day   : 'dddd'      // Monday | ||||
|                 }; | ||||
|  | ||||
|                 options.timeFormat = { | ||||
|                     'default': UiSettings.get('timeFormat') | ||||
|                 }; | ||||
|  | ||||
|                 return options; | ||||
|             }, | ||||
|  | ||||
|             _addStatusIcon: function (element, icon, tooltip) { | ||||
|                 this.$(element).find('.fc-event-time') | ||||
|                     .after('<span class="status pull-right"><i class="{0}"></i></span>'.format(icon)); | ||||
|  | ||||
|                 this.$(element).find('.status').tooltip({ | ||||
|                     title: tooltip, | ||||
|                     container: '.fc-content' | ||||
|             } | ||||
|             else if(status === 'failed') { | ||||
|                 this._addStatusIcon(element, 'icon-nd-download-failed', 'Download failed: check download client for more details'); | ||||
|             } | ||||
|             else if(status === 'warning') { | ||||
|                 this._addStatusIcon(element, 'icon-nd-download-warning', 'Download warning: check download client for more details'); | ||||
|             } | ||||
|             else { | ||||
|                 this.$(element).find('.fc-event-time').after('<span class="chart pull-right" data-percent="{0}"></span>'.format(progress)); | ||||
|                 this.$(element).find('.chart').easyPieChart({ | ||||
|                     barColor   : '#ffffff', | ||||
|                     trackColor : false, | ||||
|                     scaleColor : false, | ||||
|                     lineWidth  : 2, | ||||
|                     size       : 14, | ||||
|                     animate    : false | ||||
|                 }); | ||||
|                 this.$(element).find('.chart').tooltip({ | ||||
|                     title     : 'Episode is downloading - {0}% {1}'.format(progress.toFixed(1), releaseTitle), | ||||
|                     container : '.fc-content' | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     _getEvents            : function(view){ | ||||
|         var start = view.start.toISOString(); | ||||
|         var end = view.end.toISOString(); | ||||
|         this.$el.fullCalendar('removeEvents'); | ||||
|         this.collection.fetch({ | ||||
|             data    : { | ||||
|                 start : start, | ||||
|                 end   : end | ||||
|             }, | ||||
|             success : this._setEventData.bind(this) | ||||
|         }); | ||||
|     }); | ||||
|     }, | ||||
|     _setEventData         : function(collection){ | ||||
|         var events = []; | ||||
|         var self = this; | ||||
|         collection.each(function(model){ | ||||
|             var seriesTitle = model.get('series').title; | ||||
|             var start = model.get('airDateUtc'); | ||||
|             var runtime = model.get('series').runtime; | ||||
|             var end = moment(start).add('minutes', runtime).toISOString(); | ||||
|             var event = { | ||||
|                 title       : seriesTitle, | ||||
|                 start       : moment(start), | ||||
|                 end         : moment(end), | ||||
|                 allDay      : false, | ||||
|                 statusLevel : self._getStatusLevel(model, end), | ||||
|                 downloading : QueueCollection.findEpisode(model.get('id')), | ||||
|                 model       : model | ||||
|             }; | ||||
|             events.push(event); | ||||
|         }); | ||||
|         this.$el.fullCalendar('addEventSource', events); | ||||
|     }, | ||||
|     _getStatusLevel       : function(element, endTime){ | ||||
|         var hasFile = element.get('hasFile'); | ||||
|         var downloading = QueueCollection.findEpisode(element.get('id')) || element.get('grabbed'); | ||||
|         var currentTime = moment(); | ||||
|         var start = moment(element.get('airDateUtc')); | ||||
|         var end = moment(endTime); | ||||
|         var statusLevel = 'primary'; | ||||
|         if(hasFile) { | ||||
|             statusLevel = 'success'; | ||||
|         } | ||||
|         else if(downloading) { | ||||
|             statusLevel = 'purple'; | ||||
|         } | ||||
|         else if(currentTime.isAfter(start) && currentTime.isBefore(end)) { | ||||
|             statusLevel = 'warning'; | ||||
|         } | ||||
|         else if(start.isBefore(currentTime) && !hasFile) { | ||||
|             statusLevel = 'danger'; | ||||
|         } | ||||
|         else if(element.get('episodeNumber') === 1) { | ||||
|             statusLevel = 'premiere'; | ||||
|         } | ||||
|         if(end.isBefore(currentTime.startOf('day'))) { | ||||
|             statusLevel += ' past'; | ||||
|         } | ||||
|         return statusLevel; | ||||
|     }, | ||||
|     _reloadCalendarEvents : function(){ | ||||
|         this.$el.fullCalendar('removeEvents'); | ||||
|         this._setEventData(this.collection); | ||||
|     }, | ||||
|     _getOptions           : function(){ | ||||
|         var options = { | ||||
|             allDayDefault : false, | ||||
|             weekMode      : 'variable', | ||||
|             firstDay      : UiSettings.get('firstDayOfWeek'), | ||||
|             timeFormat    : 'h(:mm)a', | ||||
|             viewRender    : this._viewRender.bind(this), | ||||
|             eventRender   : this._eventRender.bind(this), | ||||
|             eventClick    : function(event){ | ||||
|                 vent.trigger(vent.Commands.ShowEpisodeDetails, {episode : event.model}); | ||||
|             } | ||||
|         }; | ||||
|         if($(window).width() < 768) { | ||||
|             options.defaultView = Config.getValue(this.storageKey, 'basicDay'); | ||||
|             options.header = { | ||||
|                 left   : 'prev,next today', | ||||
|                 center : 'title', | ||||
|                 right  : 'basicWeek,basicDay' | ||||
|             }; | ||||
|         } | ||||
|         else { | ||||
|             options.defaultView = Config.getValue(this.storageKey, 'basicWeek'); | ||||
|             options.header = { | ||||
|                 left   : 'prev,next today', | ||||
|                 center : 'title', | ||||
|                 right  : 'month,basicWeek,basicDay' | ||||
|             }; | ||||
|         } | ||||
|         options.titleFormat = { | ||||
|             month : 'MMMM YYYY', | ||||
|             week  : UiSettings.get('shortDateFormat'), | ||||
|             day   : UiSettings.get('longDateFormat') | ||||
|         }; | ||||
|         options.columnFormat = { | ||||
|             month : 'ddd', | ||||
|             week  : UiSettings.get('calendarWeekColumnHeader'), | ||||
|             day   : 'dddd' | ||||
|         }; | ||||
|         options.timeFormat = {"default" : UiSettings.get('timeFormat')}; | ||||
|         return options; | ||||
|     }, | ||||
|     _addStatusIcon        : function(element, icon, tooltip){ | ||||
|         this.$(element).find('.fc-event-time').after('<span class="status pull-right"><i class="{0}"></i></span>'.format(icon)); | ||||
|         this.$(element).find('.status').tooltip({ | ||||
|             title     : tooltip, | ||||
|             container : '.fc-content' | ||||
|         }); | ||||
|     } | ||||
| }); | ||||
| @@ -1,17 +1,12 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backbone', | ||||
|         'Series/EpisodeModel' | ||||
|     ], function (Backbone, EpisodeModel) { | ||||
|         return  Backbone.Collection.extend({ | ||||
|             url  : window.NzbDrone.ApiRoot + '/calendar', | ||||
|             model: EpisodeModel, | ||||
| var Backbone = require('backbone'); | ||||
| var EpisodeModel = require('../Series/EpisodeModel'); | ||||
|  | ||||
|             comparator: function (model) { | ||||
|                 var date = new Date(model.get('airDateUtc')); | ||||
|                 var time = date.getTime(); | ||||
|                 return time; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Backbone.Collection.extend({ | ||||
|     url        : window.NzbDrone.ApiRoot + '/calendar', | ||||
|     model      : EpisodeModel, | ||||
|     comparator : function(model){ | ||||
|         var date = new Date(model.get('airDateUtc')); | ||||
|         var time = date.getTime(); | ||||
|         return time; | ||||
|     } | ||||
| }); | ||||
| @@ -1,32 +1,23 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backbone', | ||||
|         'moment', | ||||
|         'Series/EpisodeModel' | ||||
|     ], function (Backbone, moment, EpisodeModel) { | ||||
|         return Backbone.Collection.extend({ | ||||
|             url  : window.NzbDrone.ApiRoot + '/calendar', | ||||
|             model: EpisodeModel, | ||||
| var Backbone = require('backbone'); | ||||
| var moment = require('moment'); | ||||
| var EpisodeModel = require('../Series/EpisodeModel'); | ||||
|  | ||||
|             comparator: function (model1, model2) { | ||||
|                 var airDate1 = model1.get('airDateUtc'); | ||||
|                 var date1 = moment(airDate1); | ||||
|                 var time1 = date1.unix(); | ||||
|  | ||||
|                 var airDate2 = model2.get('airDateUtc'); | ||||
|                 var date2 = moment(airDate2); | ||||
|                 var time2 = date2.unix(); | ||||
|  | ||||
|                 if (time1 < time2){ | ||||
|                     return -1; | ||||
|                 } | ||||
|  | ||||
|                 if (time1 > time2){ | ||||
|                     return 1; | ||||
|                 } | ||||
|  | ||||
|                 return 0; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Backbone.Collection.extend({ | ||||
|     url        : window.NzbDrone.ApiRoot + '/calendar', | ||||
|     model      : EpisodeModel, | ||||
|     comparator : function(model1, model2){ | ||||
|         var airDate1 = model1.get('airDateUtc'); | ||||
|         var date1 = moment(airDate1); | ||||
|         var time1 = date1.unix(); | ||||
|         var airDate2 = model2.get('airDateUtc'); | ||||
|         var date2 = moment(airDate2); | ||||
|         var time2 = date2.unix(); | ||||
|         if(time1 < time2) { | ||||
|             return -1; | ||||
|         } | ||||
|         if(time1 > time2) { | ||||
|             return 1; | ||||
|         } | ||||
|         return 0; | ||||
|     } | ||||
| }); | ||||
| @@ -1,30 +1,21 @@ | ||||
| 'use strict'; | ||||
| var _ = require('underscore'); | ||||
| var Marionette = require('marionette'); | ||||
| var UpcomingCollection = require('./UpcomingCollection'); | ||||
| var UpcomingItemView = require('./UpcomingItemView'); | ||||
| require('../Mixins/backbone.signalr.mixin'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'underscore', | ||||
|         'marionette', | ||||
|         'Calendar/UpcomingCollection', | ||||
|         'Calendar/UpcomingItemView', | ||||
|         'Mixins/backbone.signalr.mixin' | ||||
|     ], function (_, Marionette, UpcomingCollection, UpcomingItemView) { | ||||
|         return Marionette.CollectionView.extend({ | ||||
|             itemView: UpcomingItemView, | ||||
|  | ||||
|             initialize: function () { | ||||
|                 this.collection = new UpcomingCollection().bindSignalR({ updateOnly: true }); | ||||
|                 this.collection.fetch(); | ||||
|  | ||||
|                 this._fetchCollection = _.bind(this._fetchCollection, this); | ||||
|                 this.timer = window.setInterval(this._fetchCollection, 60 * 60 * 1000); | ||||
|             }, | ||||
|  | ||||
|             onClose: function () { | ||||
|                 window.clearInterval(this.timer); | ||||
|             }, | ||||
|  | ||||
|             _fetchCollection: function () { | ||||
|                 this.collection.fetch(); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.CollectionView.extend({ | ||||
|     itemView         : UpcomingItemView, | ||||
|     initialize       : function(){ | ||||
|         this.collection = new UpcomingCollection().bindSignalR({updateOnly : true}); | ||||
|         this.collection.fetch(); | ||||
|         this._fetchCollection = _.bind(this._fetchCollection, this); | ||||
|         this.timer = window.setInterval(this._fetchCollection, 60 * 60 * 1000); | ||||
|     }, | ||||
|     onClose          : function(){ | ||||
|         window.clearInterval(this.timer); | ||||
|     }, | ||||
|     _fetchCollection : function(){ | ||||
|         this.collection.fetch(); | ||||
|     } | ||||
| }); | ||||
| @@ -1,33 +1,19 @@ | ||||
| 'use strict'; | ||||
| var vent = require('../vent'); | ||||
| var Marionette = require('marionette'); | ||||
| var moment = require('moment'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'vent', | ||||
|         'marionette', | ||||
|         'moment' | ||||
|     ], function (vent, Marionette, moment) { | ||||
|         return Marionette.ItemView.extend({ | ||||
|             template: 'Calendar/UpcomingItemViewTemplate', | ||||
|             tagName : 'div', | ||||
|  | ||||
|             events: { | ||||
|                 'click .x-episode-title': '_showEpisodeDetails' | ||||
|             }, | ||||
|  | ||||
|             initialize: function () { | ||||
|                 var start = this.model.get('airDateUtc'); | ||||
|                 var runtime = this.model.get('series').runtime; | ||||
|                 var end = moment(start).add('minutes', runtime); | ||||
|  | ||||
|                 this.model.set({ | ||||
|                     end: end.toISOString() | ||||
|                 }); | ||||
|  | ||||
|                 this.listenTo(this.model, 'change', this.render); | ||||
|             }, | ||||
|  | ||||
|             _showEpisodeDetails: function () { | ||||
|                 vent.trigger(vent.Commands.ShowEpisodeDetails, {episode: this.model}); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.ItemView.extend({ | ||||
|     template            : 'Calendar/UpcomingItemViewTemplate', | ||||
|     tagName             : 'div', | ||||
|     events              : {"click .x-episode-title" : '_showEpisodeDetails'}, | ||||
|     initialize          : function(){ | ||||
|         var start = this.model.get('airDateUtc'); | ||||
|         var runtime = this.model.get('series').runtime; | ||||
|         var end = moment(start).add('minutes', runtime); | ||||
|         this.model.set({end : end.toISOString()}); | ||||
|         this.listenTo(this.model, 'change', this.render); | ||||
|     }, | ||||
|     _showEpisodeDetails : function(){ | ||||
|         vent.trigger(vent.Commands.ShowEpisodeDetails, {episode : this.model}); | ||||
|     } | ||||
| }); | ||||
| @@ -1,39 +1,26 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backgrid', | ||||
|         'marionette', | ||||
|         'bootstrap' | ||||
|     ], function (Backgrid, Marionette) { | ||||
| var Backgrid = require('backgrid'); | ||||
| var Marionette = require('marionette'); | ||||
| require('bootstrap'); | ||||
|  | ||||
|         return Backgrid.Cell.extend({ | ||||
|  | ||||
|             className: 'approval-status-cell', | ||||
|             template : 'Cells/ApprovalStatusCellTemplate', | ||||
|  | ||||
|             render: function () { | ||||
|  | ||||
|                 var rejections = this.model.get(this.column.get('name')); | ||||
|  | ||||
|                 if (rejections.length === 0) { | ||||
|                     return this; | ||||
|                 } | ||||
|  | ||||
|                 this.templateFunction = Marionette.TemplateCache.get(this.template); | ||||
|  | ||||
|                 var html = this.templateFunction(rejections); | ||||
|                 this.$el.html('<i class="icon-exclamation-sign"/>'); | ||||
|  | ||||
|                 this.$el.popover({ | ||||
|                     content  : html, | ||||
|                     html     : true, | ||||
|                     trigger  : 'hover', | ||||
|                     title    : 'Release Rejected', | ||||
|                     placement: 'left', | ||||
|                     container: this.$el | ||||
|                 }); | ||||
|  | ||||
|                 return this; | ||||
|             } | ||||
| module.exports = Backgrid.Cell.extend({ | ||||
|     className : 'approval-status-cell', | ||||
|     template  : 'Cells/ApprovalStatusCellTemplate', | ||||
|     render    : function(){ | ||||
|         var rejections = this.model.get(this.column.get('name')); | ||||
|         if(rejections.length === 0) { | ||||
|             return this; | ||||
|         } | ||||
|         this.templateFunction = Marionette.TemplateCache.get(this.template); | ||||
|         var html = this.templateFunction(rejections); | ||||
|         this.$el.html('<i class="icon-exclamation-sign"/>'); | ||||
|         this.$el.popover({ | ||||
|             content   : html, | ||||
|             html      : true, | ||||
|             trigger   : 'hover', | ||||
|             title     : 'Release Rejected', | ||||
|             placement : 'left', | ||||
|             container : this.$el | ||||
|         }); | ||||
|     }); | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,33 +1,20 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'vent', | ||||
|         'backgrid' | ||||
|     ], function (vent, Backgrid) { | ||||
|         return Backgrid.Cell.extend({ | ||||
| var vent = require('../vent'); | ||||
| var Backgrid = require('backgrid'); | ||||
|  | ||||
|             className : 'delete-episode-file-cell', | ||||
|  | ||||
|             events: { | ||||
|                 'click': '_onClick' | ||||
|             }, | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|                 this.$el.html('<i class="icon-nd-delete"></i>'); | ||||
|  | ||||
|                 return this; | ||||
|             }, | ||||
|  | ||||
|             _onClick: function () { | ||||
|                 var self = this; | ||||
|  | ||||
|                 if (window.confirm('Are you sure you want to delete \'{0}\' from disk?'.format(this.model.get('path')))) { | ||||
|                     this.model.destroy() | ||||
|                         .done(function () { | ||||
|                             vent.trigger(vent.Events.EpisodeFileDeleted, { episodeFile: self.model }); | ||||
|                         }); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Backgrid.Cell.extend({ | ||||
|     className : 'delete-episode-file-cell', | ||||
|     events    : {"click" : '_onClick'}, | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         this.$el.html('<i class="icon-nd-delete"></i>'); | ||||
|         return this; | ||||
|     }, | ||||
|     _onClick  : function(){ | ||||
|         var self = this; | ||||
|         if(window.confirm('Are you sure you want to delete \'{0}\' from disk?'.format(this.model.get('path')))) { | ||||
|             this.model.destroy().done(function(){ | ||||
|                 vent.trigger(vent.Events.EpisodeFileDeleted, {episodeFile : self.model}); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| }); | ||||
| @@ -1,78 +1,59 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backgrid', | ||||
|         'marionette', | ||||
|         'underscore', | ||||
|         'Settings/Profile/ProfileSchemaCollection' | ||||
|     ], function (Backgrid, Marionette, _, ProfileSchemaCollection) { | ||||
|         return Backgrid.CellEditor.extend({ | ||||
| var Backgrid = require('backgrid'); | ||||
| var Marionette = require('marionette'); | ||||
| var _ = require('underscore'); | ||||
| var ProfileSchemaCollection = require('../../Settings/Profile/ProfileSchemaCollection'); | ||||
|  | ||||
|             className: 'quality-cell-editor', | ||||
|             template : 'Cells/Edit/QualityCellEditorTemplate', | ||||
|             tagName  : 'select', | ||||
|  | ||||
|             events: { | ||||
|                 'change' : 'save', | ||||
|                 'blur'   : 'close', | ||||
|                 'keydown': 'close' | ||||
|             }, | ||||
|  | ||||
|             render: function () { | ||||
|                 var self = this; | ||||
|  | ||||
|                 var profileSchemaCollection = new ProfileSchemaCollection(); | ||||
|                 var promise = profileSchemaCollection.fetch(); | ||||
|  | ||||
|                 promise.done(function () { | ||||
|                     var templateName = self.template; | ||||
|                     self.schema = profileSchemaCollection.first(); | ||||
|  | ||||
|                     var selected = _.find(self.schema.get('items'), function (model) { | ||||
|                         return model.quality.id === self.model.get(self.column.get('name')).quality.id; | ||||
|                     }); | ||||
|  | ||||
|                     if (selected) { | ||||
|                         selected.quality.selected = true; | ||||
|                     } | ||||
|  | ||||
|                     self.templateFunction = Marionette.TemplateCache.get(templateName); | ||||
|                     var data = self.schema.toJSON(); | ||||
|                     var html = self.templateFunction(data); | ||||
|                     self.$el.html(html); | ||||
|                 }); | ||||
|  | ||||
|                 return this; | ||||
|             }, | ||||
|  | ||||
|             save: function (e) { | ||||
|                 var model = this.model; | ||||
|                 var column = this.column; | ||||
|                 var selected = parseInt(this.$el.val(), 10); | ||||
|  | ||||
|                 var profileItem = _.find(this.schema.get('items'), function(model) { | ||||
|                     return model.quality.id === selected; | ||||
|                 }); | ||||
|  | ||||
|                 var newQuality = { | ||||
|                     quality : profileItem.quality, | ||||
|                     revision : { | ||||
|                         version : 1, | ||||
|                         real    : 0 | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 model.set(column.get('name'), newQuality); | ||||
|                 model.save(); | ||||
|                 model.trigger('backgrid:edited', model, column, new Backgrid.Command(e)); | ||||
|             }, | ||||
|  | ||||
|             close: function (e) { | ||||
|                 var model = this.model; | ||||
|                 var column = this.column; | ||||
|                 var command = new Backgrid.Command(e); | ||||
|  | ||||
|                 model.trigger('backgrid:edited', model, column, command); | ||||
| module.exports = Backgrid.CellEditor.extend({ | ||||
|     className : 'quality-cell-editor', | ||||
|     template  : 'Cells/Edit/QualityCellEditorTemplate', | ||||
|     tagName   : 'select', | ||||
|     events    : { | ||||
|         "change"  : 'save', | ||||
|         "blur"    : 'close', | ||||
|         "keydown" : 'close' | ||||
|     }, | ||||
|     render    : function(){ | ||||
|         var self = this; | ||||
|         var profileSchemaCollection = new ProfileSchemaCollection(); | ||||
|         var promise = profileSchemaCollection.fetch(); | ||||
|         promise.done(function(){ | ||||
|             var templateName = self.template; | ||||
|             self.schema = profileSchemaCollection.first(); | ||||
|             var selected = _.find(self.schema.get('items'), function(model){ | ||||
|                 return model.quality.id === self.model.get(self.column.get('name')).quality.id; | ||||
|             }); | ||||
|             if(selected) { | ||||
|                 selected.quality.selected = true; | ||||
|             } | ||||
|             self.templateFunction = Marionette.TemplateCache.get(templateName); | ||||
|             var data = self.schema.toJSON(); | ||||
|             var html = self.templateFunction(data); | ||||
|             self.$el.html(html); | ||||
|         }); | ||||
|     }); | ||||
|         return this; | ||||
|     }, | ||||
|     save      : function(e){ | ||||
|         var model = this.model; | ||||
|         var column = this.column; | ||||
|         var selected = parseInt(this.$el.val(), 10); | ||||
|         var profileItem = _.find(this.schema.get('items'), function(model){ | ||||
|             return model.quality.id === selected; | ||||
|         }); | ||||
|         var newQuality = { | ||||
|             quality  : profileItem.quality, | ||||
|             revision : { | ||||
|                 version : 1, | ||||
|                 real    : 0 | ||||
|             } | ||||
|         }; | ||||
|         model.set(column.get('name'), newQuality); | ||||
|         model.save(); | ||||
|         model.trigger('backgrid:edited', model, column, new Backgrid.Command(e)); | ||||
|     }, | ||||
|     close     : function(e){ | ||||
|         var model = this.model; | ||||
|         var column = this.column; | ||||
|         var command = new Backgrid.Command(e); | ||||
|         model.trigger('backgrid:edited', model, column, command); | ||||
|     } | ||||
| }); | ||||
| @@ -1,49 +1,37 @@ | ||||
| 'use strict'; | ||||
| var vent = require('../vent'); | ||||
| var NzbDroneCell = require('./NzbDroneCell'); | ||||
| var CommandController = require('../Commands/CommandController'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'vent', | ||||
|         'Cells/NzbDroneCell', | ||||
|         'Commands/CommandController' | ||||
|     ], function (vent, NzbDroneCell, CommandController) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className: 'episode-actions-cell', | ||||
|  | ||||
|             events: { | ||||
|                 'click .x-automatic-search' : '_automaticSearch', | ||||
|                 'click .x-manual-search'    : '_manualSearch' | ||||
|             }, | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|  | ||||
|                 this.$el.html( | ||||
|                     '<i class="icon-search x-automatic-search" title="Automatic Search"></i>' + | ||||
|                     '<i class="icon-nd-manual-search x-manual-search" title="Manual Search"></i>' | ||||
|                 ); | ||||
|  | ||||
|                 CommandController.bindToCommand({ | ||||
|                     element: this.$el.find('.x-automatic-search'), | ||||
|                     command: { | ||||
|                         name       : 'episodeSearch', | ||||
|                         episodeIds : [ this.model.get('id') ] | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|                 this.delegateEvents(); | ||||
|                 return this; | ||||
|             }, | ||||
|  | ||||
|             _automaticSearch: function () { | ||||
|                 CommandController.Execute('episodeSearch', { | ||||
|                     name       : 'episodeSearch', | ||||
|                     episodeIds : [ this.model.get('id') ] | ||||
|                 }); | ||||
|             }, | ||||
|  | ||||
|             _manualSearch: function () { | ||||
|                 vent.trigger(vent.Commands.ShowEpisodeDetails, { episode: this.cellValue, hideSeriesLink: true, openingTab: 'search' }); | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className        : 'episode-actions-cell', | ||||
|     events           : { | ||||
|         "click .x-automatic-search" : '_automaticSearch', | ||||
|         "click .x-manual-search"    : '_manualSearch' | ||||
|     }, | ||||
|     render           : function(){ | ||||
|         this.$el.empty(); | ||||
|         this.$el.html('<i class="icon-search x-automatic-search" title="Automatic Search"></i>' + '<i class="icon-nd-manual-search x-manual-search" title="Manual Search"></i>'); | ||||
|         CommandController.bindToCommand({ | ||||
|             element : this.$el.find('.x-automatic-search'), | ||||
|             command : { | ||||
|                 name       : 'episodeSearch', | ||||
|                 episodeIds : [this.model.get('id')] | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|         this.delegateEvents(); | ||||
|         return this; | ||||
|     }, | ||||
|     _automaticSearch : function(){ | ||||
|         CommandController.Execute('episodeSearch', { | ||||
|             name       : 'episodeSearch', | ||||
|             episodeIds : [this.model.get('id')] | ||||
|         }); | ||||
|     }, | ||||
|     _manualSearch    : function(){ | ||||
|         vent.trigger(vent.Commands.ShowEpisodeDetails, { | ||||
|             episode        : this.cellValue, | ||||
|             hideSeriesLink : true, | ||||
|             openingTab     : 'search' | ||||
|         }); | ||||
|     } | ||||
| }); | ||||
| @@ -1,63 +1,42 @@ | ||||
| 'use strict'; | ||||
| var _ = require('underscore'); | ||||
| var ToggleCell = require('./ToggleCell'); | ||||
| var SeriesCollection = require('../Series/SeriesCollection'); | ||||
| var Messenger = require('../Shared/Messenger'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'underscore', | ||||
|         'Cells/ToggleCell', | ||||
|         'Series/SeriesCollection', | ||||
|         'Shared/Messenger' | ||||
|     ], function (_, ToggleCell, SeriesCollection, Messenger) { | ||||
|         return ToggleCell.extend({ | ||||
|  | ||||
|             className: 'toggle-cell episode-monitored', | ||||
|  | ||||
|             _originalOnClick: ToggleCell.prototype._onClick, | ||||
|  | ||||
|             _onClick: function (e) { | ||||
|  | ||||
|                 var series = SeriesCollection.get(this.model.get('seriesId')); | ||||
|  | ||||
|                 if (!series.get('monitored')) { | ||||
|  | ||||
|                     Messenger.show({ | ||||
|                         message: 'Unable to change monitored state when series is not monitored', | ||||
|                         type   : 'error' | ||||
|                     }); | ||||
|  | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (e.shiftKey && this.model.episodeCollection.lastToggled) { | ||||
|                     this._selectRange(); | ||||
|  | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 this._originalOnClick.apply(this, arguments); | ||||
|                 this.model.episodeCollection.lastToggled = this.model; | ||||
|             }, | ||||
|  | ||||
|             _selectRange: function () { | ||||
|                 var episodeCollection = this.model.episodeCollection; | ||||
|                 var lastToggled = episodeCollection.lastToggled; | ||||
|  | ||||
|                 var currentIndex = episodeCollection.indexOf(this.model); | ||||
|                 var lastIndex = episodeCollection.indexOf(lastToggled); | ||||
|  | ||||
|                 var low = Math.min(currentIndex, lastIndex); | ||||
|                 var high = Math.max(currentIndex, lastIndex); | ||||
|                 var range = _.range(low + 1, high); | ||||
|  | ||||
|                 _.each(range, function (index) { | ||||
|                     var model = episodeCollection.at(index); | ||||
|  | ||||
|                     model.set('monitored', lastToggled.get('monitored')); | ||||
|                     model.save(); | ||||
|                 }); | ||||
|  | ||||
|                 this.model.set('monitored', lastToggled.get('monitored')); | ||||
|                 this.model.save(); | ||||
|                 this.model.episodeCollection.lastToggled = undefined; | ||||
|             } | ||||
| module.exports = ToggleCell.extend({ | ||||
|     className        : 'toggle-cell episode-monitored', | ||||
|     _originalOnClick : ToggleCell.prototype._onClick, | ||||
|     _onClick         : function(e){ | ||||
|         var series = SeriesCollection.get(this.model.get('seriesId')); | ||||
|         if(!series.get('monitored')) { | ||||
|             Messenger.show({ | ||||
|                 message : 'Unable to change monitored state when series is not monitored', | ||||
|                 type    : 'error' | ||||
|             }); | ||||
|             return; | ||||
|         } | ||||
|         if(e.shiftKey && this.model.episodeCollection.lastToggled) { | ||||
|             this._selectRange(); | ||||
|             return; | ||||
|         } | ||||
|         this._originalOnClick.apply(this, arguments); | ||||
|         this.model.episodeCollection.lastToggled = this.model; | ||||
|     }, | ||||
|     _selectRange     : function(){ | ||||
|         var episodeCollection = this.model.episodeCollection; | ||||
|         var lastToggled = episodeCollection.lastToggled; | ||||
|         var currentIndex = episodeCollection.indexOf(this.model); | ||||
|         var lastIndex = episodeCollection.indexOf(lastToggled); | ||||
|         var low = Math.min(currentIndex, lastIndex); | ||||
|         var high = Math.max(currentIndex, lastIndex); | ||||
|         var range = _.range(low + 1, high); | ||||
|         _.each(range, function(index){ | ||||
|             var model = episodeCollection.at(index); | ||||
|             model.set('monitored', lastToggled.get('monitored')); | ||||
|             model.save(); | ||||
|         }); | ||||
|     }); | ||||
|         this.model.set('monitored', lastToggled.get('monitored')); | ||||
|         this.model.save(); | ||||
|         this.model.episodeCollection.lastToggled = undefined; | ||||
|     } | ||||
| }); | ||||
| @@ -1,79 +1,58 @@ | ||||
|  'use strict'; | ||||
| var NzbDroneCell = require('./NzbDroneCell'); | ||||
| var FormatHelpers = require('../Shared/FormatHelpers'); | ||||
| var _ = require('underscore'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'Cells/NzbDroneCell', | ||||
|         'Shared/FormatHelpers', | ||||
|         'underscore' | ||||
|     ], function (NzbDroneCell, FormatHelpers, _) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className: 'episode-number-cell', | ||||
|  | ||||
|             render: function () { | ||||
|  | ||||
|                 this.$el.empty(); | ||||
|  | ||||
|                 var airDateField = this.column.get('airDateUtc') || 'airDateUtc'; | ||||
|                 var seasonField = this.column.get('seasonNumber') || 'seasonNumber'; | ||||
|                 var episodeField = this.column.get('episodes') || 'episodeNumber'; | ||||
|                 var absoluteEpisodeField = 'absoluteEpisodeNumber'; | ||||
|  | ||||
|                 if (this.model) { | ||||
|                     var result = 'Unknown'; | ||||
|  | ||||
|                     var airDate = this.model.get(airDateField); | ||||
|                     var seasonNumber = this.model.get(seasonField); | ||||
|                     var episodes = this.model.get(episodeField); | ||||
|                     var absoluteEpisodeNumber = this.model.get(absoluteEpisodeField); | ||||
|  | ||||
|                     if (this.cellValue) { | ||||
|                         if (!seasonNumber) { | ||||
|                             seasonNumber = this.cellValue.get(seasonField); | ||||
|                         } | ||||
|  | ||||
|                         if (!episodes) { | ||||
|                             episodes = this.cellValue.get(episodeField); | ||||
|                         } | ||||
|  | ||||
|                         if (absoluteEpisodeNumber === undefined) { | ||||
|                             absoluteEpisodeNumber = this.cellValue.get(absoluteEpisodeField); | ||||
|                         } | ||||
|  | ||||
|                         if (!airDate) { | ||||
|                             this.model.get(airDateField); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     if (episodes) { | ||||
|  | ||||
|                         var paddedEpisodes; | ||||
|                         var paddedAbsoluteEpisode; | ||||
|  | ||||
|                         if (episodes.constructor === Array) { | ||||
|                             paddedEpisodes = _.map(episodes,function (episodeNumber) { | ||||
|                                 return FormatHelpers.pad(episodeNumber, 2); | ||||
|                             }).join(); | ||||
|                         } | ||||
|                         else { | ||||
|                             paddedEpisodes = FormatHelpers.pad(episodes, 2); | ||||
|                             paddedAbsoluteEpisode = FormatHelpers.pad(absoluteEpisodeNumber, 2); | ||||
|                         } | ||||
|  | ||||
|                         result = '{0}x{1}'.format(seasonNumber, paddedEpisodes); | ||||
|  | ||||
|                         if (absoluteEpisodeNumber !== undefined && paddedAbsoluteEpisode) { | ||||
|                             result += ' ({0})'.format(paddedAbsoluteEpisode); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (airDate) { | ||||
|                         result = new Date(airDate).toLocaleDateString(); | ||||
|                     } | ||||
|  | ||||
|                     this.$el.html(result); | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className : 'episode-number-cell', | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         var airDateField = this.column.get('airDateUtc') || 'airDateUtc'; | ||||
|         var seasonField = this.column.get('seasonNumber') || 'seasonNumber'; | ||||
|         var episodeField = this.column.get('episodes') || 'episodeNumber'; | ||||
|         var absoluteEpisodeField = 'absoluteEpisodeNumber'; | ||||
|         if(this.model) { | ||||
|             var result = 'Unknown'; | ||||
|             var airDate = this.model.get(airDateField); | ||||
|             var seasonNumber = this.model.get(seasonField); | ||||
|             var episodes = this.model.get(episodeField); | ||||
|             var absoluteEpisodeNumber = this.model.get(absoluteEpisodeField); | ||||
|             if(this.cellValue) { | ||||
|                 if(!seasonNumber) { | ||||
|                     seasonNumber = this.cellValue.get(seasonField); | ||||
|                 } | ||||
|                 if(!episodes) { | ||||
|                     episodes = this.cellValue.get(episodeField); | ||||
|                 } | ||||
|                 if(absoluteEpisodeNumber === undefined) { | ||||
|                     absoluteEpisodeNumber = this.cellValue.get(absoluteEpisodeField); | ||||
|                 } | ||||
|                 if(!airDate) { | ||||
|                     this.model.get(airDateField); | ||||
|                 } | ||||
|                 this.delegateEvents(); | ||||
|                 return this; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|             if(episodes) { | ||||
|                 var paddedEpisodes; | ||||
|                 var paddedAbsoluteEpisode; | ||||
|                 if(episodes.constructor === Array) { | ||||
|                     paddedEpisodes = _.map(episodes, function(episodeNumber){ | ||||
|                         return FormatHelpers.pad(episodeNumber, 2); | ||||
|                     }).join(); | ||||
|                 } | ||||
|                 else { | ||||
|                     paddedEpisodes = FormatHelpers.pad(episodes, 2); | ||||
|                     paddedAbsoluteEpisode = FormatHelpers.pad(absoluteEpisodeNumber, 2); | ||||
|                 } | ||||
|                 result = '{0}x{1}'.format(seasonNumber, paddedEpisodes); | ||||
|                 if(absoluteEpisodeNumber !== undefined && paddedAbsoluteEpisode) { | ||||
|                     result += ' ({0})'.format(paddedAbsoluteEpisode); | ||||
|                 } | ||||
|             } | ||||
|             else if(airDate) { | ||||
|                 result = new Date(airDate).toLocaleDateString(); | ||||
|             } | ||||
|             this.$el.html(result); | ||||
|         } | ||||
|         this.delegateEvents(); | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,33 +1,21 @@ | ||||
| 'use strict'; | ||||
| var Marionette = require('marionette'); | ||||
| var NzbDroneCell = require('./NzbDroneCell'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function (Marionette, NzbDroneCell) { | ||||
|         return 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; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| 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,135 +1,98 @@ | ||||
| 'use strict'; | ||||
| 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'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'reqres', | ||||
|         'backbone', | ||||
|         'Cells/NzbDroneCell', | ||||
|         'Activity/Queue/QueueCollection', | ||||
|         'moment', | ||||
|         'Shared/FormatHelpers' | ||||
|     ], function (reqres, Backbone, NzbDroneCell, QueueCollection, moment, FormatHelpers) { | ||||
|         return  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); | ||||
| 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]'; | ||||
|                 } | ||||
|  | ||||
|                 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)); | ||||
|                         } | ||||
|  | ||||
|                 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-nd-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 { | ||||
|                         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-nd-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-nd-downloading'; | ||||
|                             tooltip = 'Episode is downloading'; | ||||
|                         } | ||||
|  | ||||
|                         else if (!this.model.get('airDateUtc')) { | ||||
|                             icon = 'icon-nd-tba'; | ||||
|                             tooltip = 'TBA'; | ||||
|                         } | ||||
|  | ||||
|                         else if (hasAired) { | ||||
|                             icon = 'icon-nd-missing'; | ||||
|                             tooltip = 'Episode missing from disk'; | ||||
|                         } | ||||
|                         else { | ||||
|                             icon = 'icon-nd-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; | ||||
|                     } | ||||
|                 else if(this.model.get('grabbed')) { | ||||
|                     icon = 'icon-nd-downloading'; | ||||
|                     tooltip = 'Episode is downloading'; | ||||
|                 } | ||||
|                 else if(!this.model.get('airDateUtc')) { | ||||
|                     icon = 'icon-nd-tba'; | ||||
|                     tooltip = 'TBA'; | ||||
|                 } | ||||
|                 else if(hasAired) { | ||||
|                     icon = 'icon-nd-missing'; | ||||
|                     tooltip = 'Episode missing from disk'; | ||||
|                 } | ||||
|                 else { | ||||
|                     icon = 'icon-nd-not-aired'; | ||||
|                     tooltip = 'Episode has not aired'; | ||||
|                 } | ||||
|  | ||||
|                 return undefined; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|             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,33 +1,22 @@ | ||||
| 'use strict'; | ||||
| var vent = require('../vent'); | ||||
| var NzbDroneCell = require('./NzbDroneCell'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'vent', | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function (vent, NzbDroneCell) { | ||||
|         return 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 }); | ||||
|             } | ||||
| 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,52 +1,39 @@ | ||||
| 'use strict'; | ||||
| var NzbDroneCell = require('./NzbDroneCell'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function (NzbDroneCell) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className: 'history-event-type-cell', | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|  | ||||
|                 if (this.cellValue) { | ||||
|  | ||||
|                     var icon; | ||||
|                     var toolTip; | ||||
|  | ||||
|                     switch (this.cellValue.get('eventType')) { | ||||
|                         case 'grabbed': | ||||
|                             icon = 'icon-nd-downloading'; | ||||
|                             toolTip = 'Episode grabbed from {0} and sent to download client'.format(this.cellValue.get('data').indexer); | ||||
|                             break; | ||||
|                         case 'seriesFolderImported': | ||||
|                             icon = 'icon-hdd'; | ||||
|                             toolTip = 'Existing episode file added to library'; | ||||
|                             break; | ||||
|                         case 'downloadFolderImported': | ||||
|                             icon = 'icon-nd-imported'; | ||||
|                             toolTip = 'Episode downloaded successfully and picked up from download client'; | ||||
|                             break; | ||||
|                         case 'downloadFailed': | ||||
|                             icon = 'icon-nd-download-failed'; | ||||
|                             toolTip = 'Episode download failed'; | ||||
|                             break; | ||||
|                         case 'episodeFileDeleted': | ||||
|                             icon = 'icon-nd-deleted'; | ||||
|                             toolTip = 'Episode file deleted'; | ||||
|                             break; | ||||
|                         default : | ||||
|                             icon = 'icon-question'; | ||||
|                             toolTip = 'unknown event'; | ||||
|  | ||||
|                     } | ||||
|  | ||||
|                     this.$el.html('<i class="{0}" title="{1}" data-placement="right"/>'.format(icon, toolTip)); | ||||
|                 } | ||||
|  | ||||
|                 return this; | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className : 'history-event-type-cell', | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         if(this.cellValue) { | ||||
|             var icon; | ||||
|             var toolTip; | ||||
|             switch (this.cellValue.get('eventType')) { | ||||
|                 case 'grabbed': | ||||
|                     icon = 'icon-nd-downloading'; | ||||
|                     toolTip = 'Episode grabbed from {0} and sent to download client'.format(this.cellValue.get('data').indexer); | ||||
|                     break; | ||||
|                 case 'seriesFolderImported': | ||||
|                     icon = 'icon-hdd'; | ||||
|                     toolTip = 'Existing episode file added to library'; | ||||
|                     break; | ||||
|                 case 'downloadFolderImported': | ||||
|                     icon = 'icon-nd-imported'; | ||||
|                     toolTip = 'Episode downloaded successfully and picked up from download client'; | ||||
|                     break; | ||||
|                 case 'downloadFailed': | ||||
|                     icon = 'icon-nd-download-failed'; | ||||
|                     toolTip = 'Episode download failed'; | ||||
|                     break; | ||||
|                 case 'episodeFileDeleted': | ||||
|                     icon = 'icon-nd-deleted'; | ||||
|                     toolTip = 'Episode file deleted'; | ||||
|                     break; | ||||
|                 default: | ||||
|                     icon = 'icon-question'; | ||||
|                     toolTip = 'unknown event'; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|             this.$el.html('<i class="{0}" title="{1}" data-placement="right"/>'.format(icon, toolTip)); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,19 +1,12 @@ | ||||
| 'use strict'; | ||||
| var Backgrid = require('backgrid'); | ||||
| var FormatHelpers = require('../Shared/FormatHelpers'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'backgrid', | ||||
|         'Shared/FormatHelpers' | ||||
|     ], function (Backgrid, FormatHelpers) { | ||||
|         return Backgrid.Cell.extend({ | ||||
|  | ||||
|             className: 'file-size-cell', | ||||
|  | ||||
|             render: function () { | ||||
|                 var size = this.model.get(this.column.get('name')); | ||||
|                 this.$el.html(FormatHelpers.bytes(size)); | ||||
|                 this.delegateEvents(); | ||||
|                 return this; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Backgrid.Cell.extend({ | ||||
|     className : 'file-size-cell', | ||||
|     render    : function(){ | ||||
|         var size = this.model.get(this.column.get('name')); | ||||
|         this.$el.html(FormatHelpers.bytes(size)); | ||||
|         this.delegateEvents(); | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,16 +1,10 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backgrid' | ||||
|     ], function (Backgrid) { | ||||
|         return Backgrid.Cell.extend({ | ||||
| var Backgrid = require('backgrid'); | ||||
|  | ||||
|             className : 'indexer-cell', | ||||
|  | ||||
|             render: function () { | ||||
|                 var indexer = this.model.get(this.column.get('name')); | ||||
|                 this.$el.html(indexer); | ||||
|                 return this; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Backgrid.Cell.extend({ | ||||
|     className : 'indexer-cell', | ||||
|     render    : function(){ | ||||
|         var indexer = this.model.get(this.column.get('name')); | ||||
|         this.$el.html(indexer); | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,63 +1,42 @@ | ||||
| 'use strict'; | ||||
| var Backgrid = require('backgrid'); | ||||
| var Backbone = require('backbone'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'backgrid', | ||||
|         'backbone' | ||||
|     ], function (Backgrid, Backbone) { | ||||
|         return Backgrid.Cell.extend({ | ||||
|  | ||||
|             _originalInit: Backgrid.Cell.prototype.initialize, | ||||
|  | ||||
|             initialize: function () { | ||||
|                 this._originalInit.apply(this, arguments); | ||||
|                 this.cellValue = this._getValue(); | ||||
|  | ||||
|                 this.listenTo(this.model, 'change', this._refresh); | ||||
|  | ||||
|                 if (this._onEdit) { | ||||
|                     this.listenTo(this.model, 'backgrid:edit', function (model, column, cell, editor) { | ||||
|                         if (column.get('name') === this.column.get('name')) { | ||||
|                             this._onEdit(model, column, cell, editor); | ||||
|                         } | ||||
|                     }); | ||||
| module.exports = Backgrid.Cell.extend({ | ||||
|     _originalInit : Backgrid.Cell.prototype.initialize, | ||||
|     initialize    : function(){ | ||||
|         this._originalInit.apply(this, arguments); | ||||
|         this.cellValue = this._getValue(); | ||||
|         this.listenTo(this.model, 'change', this._refresh); | ||||
|         if(this._onEdit) { | ||||
|             this.listenTo(this.model, 'backgrid:edit', function(model, column, cell, editor){ | ||||
|                 if(column.get('name') === this.column.get('name')) { | ||||
|                     this._onEdit(model, column, cell, editor); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             _refresh: function () { | ||||
|                 this.cellValue = this._getValue(); | ||||
|                 this.render(); | ||||
|             }, | ||||
|  | ||||
|             _getValue: function () { | ||||
|  | ||||
|                 var cellValue = this.column.get('cellValue'); | ||||
|  | ||||
|                 if (cellValue) { | ||||
|                     if (cellValue === 'this') { | ||||
|                         return this.model; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 var name = this.column.get('name'); | ||||
|  | ||||
|                 if (name === 'this') { | ||||
|                     return this.model; | ||||
|                 } | ||||
|  | ||||
|                 var value = this.model.get(name); | ||||
|  | ||||
|                 if (!value) { | ||||
|                     return undefined; | ||||
|                 } | ||||
|  | ||||
|                 //if not a model | ||||
|                 if (!value.get && typeof value === 'object') { | ||||
|                     value = new Backbone.Model(value); | ||||
|                 } | ||||
|  | ||||
|                 return value; | ||||
|             }); | ||||
|         } | ||||
|     }, | ||||
|     _refresh      : function(){ | ||||
|         this.cellValue = this._getValue(); | ||||
|         this.render(); | ||||
|     }, | ||||
|     _getValue     : function(){ | ||||
|         var cellValue = this.column.get('cellValue'); | ||||
|         if(cellValue) { | ||||
|             if(cellValue === 'this') { | ||||
|                 return this.model; | ||||
|             } | ||||
|  | ||||
|         }); | ||||
|     }); | ||||
|         } | ||||
|         var name = this.column.get('name'); | ||||
|         if(name === 'this') { | ||||
|             return this.model; | ||||
|         } | ||||
|         var value = this.model.get(name); | ||||
|         if(!value) { | ||||
|             return undefined; | ||||
|         } | ||||
|         if(!value.get && typeof value === 'object') { | ||||
|             value = new Backbone.Model(value); | ||||
|         } | ||||
|         return value; | ||||
|     } | ||||
| }); | ||||
| @@ -1,25 +1,16 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backgrid', | ||||
|         'Profile/ProfileCollection', | ||||
|         'underscore' | ||||
|     ], function (Backgrid, ProfileCollection,_) { | ||||
|         return Backgrid.Cell.extend({ | ||||
|             className: 'profile-cell', | ||||
| var Backgrid = require('backgrid'); | ||||
| var ProfileCollection = require('../Profile/ProfileCollection'); | ||||
| var _ = require('underscore'); | ||||
|  | ||||
|             render: function () { | ||||
|  | ||||
|                 this.$el.empty(); | ||||
|                 var profileId = this.model.get(this.column.get('name')); | ||||
|  | ||||
|                 var profile = _.findWhere(ProfileCollection.models, { id: profileId }); | ||||
|  | ||||
|                 if (profile) { | ||||
|                     this.$el.html(profile.get('name')); | ||||
|                 } | ||||
|  | ||||
|                 return this; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Backgrid.Cell.extend({ | ||||
|     className : 'profile-cell', | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         var profileId = this.model.get(this.column.get('name')); | ||||
|         var profile = _.findWhere(ProfileCollection.models, {id : profileId}); | ||||
|         if(profile) { | ||||
|             this.$el.html(profile.get('name')); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,13 +1,8 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'Cells/TemplatedCell', | ||||
|         'Cells/Edit/QualityCellEditor' | ||||
|     ], function (TemplatedCell, QualityCellEditor) { | ||||
|         return TemplatedCell.extend({ | ||||
| var TemplatedCell = require('./TemplatedCell'); | ||||
| var QualityCellEditor = require('./Edit/QualityCellEditor'); | ||||
|  | ||||
|             className: 'quality-cell', | ||||
|             template : 'Cells/QualityCellTemplate', | ||||
|             editor   : QualityCellEditor | ||||
|         }); | ||||
|     }); | ||||
| module.exports = TemplatedCell.extend({ | ||||
|     className : 'quality-cell', | ||||
|     template  : 'Cells/QualityCellTemplate', | ||||
|     editor    : QualityCellEditor | ||||
| }); | ||||
| @@ -1,37 +1,25 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'Cells/NzbDroneCell', | ||||
|         'moment', | ||||
|         'Shared/FormatHelpers', | ||||
|         'Shared/UiSettingsModel' | ||||
|     ], function (NzbDroneCell, moment, FormatHelpers, UiSettings) { | ||||
|         return NzbDroneCell.extend({ | ||||
| var NzbDroneCell = require('./NzbDroneCell'); | ||||
| var moment = require('moment'); | ||||
| var FormatHelpers = require('../Shared/FormatHelpers'); | ||||
| var UiSettings = require('../Shared/UiSettingsModel'); | ||||
|  | ||||
|             className: 'relative-date-cell', | ||||
|  | ||||
|             render: function () { | ||||
|  | ||||
|                 var dateStr = this.model.get(this.column.get('name')); | ||||
|  | ||||
|                 if (dateStr) { | ||||
|                     var date = moment(dateStr); | ||||
|                     var result = '<span title="{0}">{1}</span>'; | ||||
|                     var tooltip = date.format(UiSettings.longDateTime()); | ||||
|                     var text; | ||||
|  | ||||
|                     if (UiSettings.get('showRelativeDates')) { | ||||
|                         text = FormatHelpers.relativeDate(dateStr); | ||||
|                     } | ||||
|  | ||||
|                     else { | ||||
|                         text = date.format(UiSettings.get('shortDateFormat')); | ||||
|                     } | ||||
|  | ||||
|                     this.$el.html(result.format(tooltip, text)); | ||||
|                 } | ||||
|  | ||||
|                 return this; | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className : 'relative-date-cell', | ||||
|     render    : function(){ | ||||
|         var dateStr = this.model.get(this.column.get('name')); | ||||
|         if(dateStr) { | ||||
|             var date = moment(dateStr); | ||||
|             var result = '<span title="{0}">{1}</span>'; | ||||
|             var tooltip = date.format(UiSettings.longDateTime()); | ||||
|             var text; | ||||
|             if(UiSettings.get('showRelativeDates')) { | ||||
|                 text = FormatHelpers.relativeDate(dateStr); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|             else { | ||||
|                 text = date.format(UiSettings.get('shortDateFormat')); | ||||
|             } | ||||
|             this.$el.html(result.format(tooltip, text)); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,37 +1,25 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'Cells/NzbDroneCell', | ||||
|         'moment', | ||||
|         'Shared/FormatHelpers', | ||||
|         'Shared/UiSettingsModel' | ||||
|     ], function (NzbDroneCell, moment, FormatHelpers, UiSettings) { | ||||
|         return NzbDroneCell.extend({ | ||||
| var NzbDroneCell = require('./NzbDroneCell'); | ||||
| var moment = require('moment'); | ||||
| var FormatHelpers = require('../Shared/FormatHelpers'); | ||||
| var UiSettings = require('../Shared/UiSettingsModel'); | ||||
|  | ||||
|             className: 'relative-time-cell', | ||||
|  | ||||
|             render: function () { | ||||
|  | ||||
|                 var dateStr = this.model.get(this.column.get('name')); | ||||
|  | ||||
|                 if (dateStr) { | ||||
|                     var date = moment(dateStr); | ||||
|                     var result = '<span title="{0}">{1}</span>'; | ||||
|                     var tooltip = date.format(UiSettings.longDateTime()); | ||||
|                     var text; | ||||
|  | ||||
|                     if (UiSettings.get('showRelativeDates')) { | ||||
|                         text = date.fromNow(); | ||||
|                     } | ||||
|  | ||||
|                     else { | ||||
|                         text = date.format(UiSettings.shortDateTime()); | ||||
|                     } | ||||
|  | ||||
|                     this.$el.html(result.format(tooltip, text)); | ||||
|                 } | ||||
|  | ||||
|                 return this; | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className : 'relative-time-cell', | ||||
|     render    : function(){ | ||||
|         var dateStr = this.model.get(this.column.get('name')); | ||||
|         if(dateStr) { | ||||
|             var date = moment(dateStr); | ||||
|             var result = '<span title="{0}">{1}</span>'; | ||||
|             var tooltip = date.format(UiSettings.longDateTime()); | ||||
|             var text; | ||||
|             if(UiSettings.get('showRelativeDates')) { | ||||
|                 text = date.fromNow(); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|             else { | ||||
|                 text = date.format(UiSettings.shortDateTime()); | ||||
|             } | ||||
|             this.$el.html(result.format(tooltip, text)); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,28 +1,17 @@ | ||||
| 'use strict'; | ||||
| var NzbDroneCell = require('./NzbDroneCell'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function (NzbDroneCell) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className: 'release-title-cell', | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|  | ||||
|                 var title = this.model.get('title'); | ||||
|                 var infoUrl = this.model.get('infoUrl'); | ||||
|  | ||||
|                 if (infoUrl) { | ||||
|                     this.$el.html('<a href="{0}">{1}</a>'.format(infoUrl, title)); | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     this.$el.html(title); | ||||
|                 } | ||||
|  | ||||
|                 return this; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className : 'release-title-cell', | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         var title = this.model.get('title'); | ||||
|         var infoUrl = this.model.get('infoUrl'); | ||||
|         if(infoUrl) { | ||||
|             this.$el.html('<a href="{0}">{1}</a>'.format(infoUrl, title)); | ||||
|         } | ||||
|         else { | ||||
|             this.$el.html(title); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,19 +1,11 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backgrid' | ||||
|     ], function (Backgrid) { | ||||
|         return Backgrid.Cell.extend({ | ||||
| var Backgrid = require('backgrid'); | ||||
|  | ||||
|             className : 'season-folder-cell', | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|  | ||||
|                 var seasonFolder = this.model.get(this.column.get('name')); | ||||
|                 this.$el.html(seasonFolder.toString()); | ||||
|  | ||||
|                 return this; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Backgrid.Cell.extend({ | ||||
|     className : 'season-folder-cell', | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         var seasonFolder = this.model.get(this.column.get('name')); | ||||
|         this.$el.html(seasonFolder.toString()); | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,49 +1,35 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'jquery', | ||||
|         'underscore', | ||||
|         'backgrid.selectall' | ||||
|     ], function ($, _, BackgridSelectAll) { | ||||
|         return BackgridSelectAll.extend({ | ||||
| var $ = require('jquery'); | ||||
| var _ = require('underscore'); | ||||
| var BackgridSelectAll = require('backgrid.selectall'); | ||||
|  | ||||
|             enterEditMode: function (e) { | ||||
|                 if (e.shiftKey && this.model.collection.lastToggled) { | ||||
|                     this._selectRange(); | ||||
|                 } | ||||
|  | ||||
|                 var checked = $(e.target).prop('checked'); | ||||
|  | ||||
|                 this.model.collection.lastToggled = this.model; | ||||
|                 this.model.collection.checked = checked; | ||||
|             }, | ||||
|  | ||||
|             onChange: function (e) { | ||||
|                 var checked = $(e.target).prop('checked'); | ||||
|                 this.$el.parent().toggleClass('selected', checked); | ||||
|                 this.model.trigger('backgrid:selected', this.model, checked); | ||||
|             }, | ||||
|  | ||||
|             _selectRange: function () { | ||||
|                 var collection = this.model.collection; | ||||
|                 var lastToggled = collection.lastToggled; | ||||
|                 var checked = collection.checked; | ||||
|  | ||||
|                 var currentIndex = collection.indexOf(this.model); | ||||
|                 var lastIndex = collection.indexOf(lastToggled); | ||||
|  | ||||
|                 var low = Math.min(currentIndex, lastIndex); | ||||
|                 var high = Math.max(currentIndex, lastIndex); | ||||
|                 var range = _.range(low + 1, high); | ||||
|  | ||||
|                 _.each(range, function (index) { | ||||
|                     var model = collection.at(index); | ||||
|  | ||||
|                     model.trigger('backgrid:select', model, checked); | ||||
|                 }); | ||||
|  | ||||
|                 this.model.collection.lastToggled = undefined; | ||||
|                 this.model.collection.checked = undefined; | ||||
|             } | ||||
| module.exports = BackgridSelectAll.extend({ | ||||
|     enterEditMode : function(e){ | ||||
|         if(e.shiftKey && this.model.collection.lastToggled) { | ||||
|             this._selectRange(); | ||||
|         } | ||||
|         var checked = $(e.target).prop('checked'); | ||||
|         this.model.collection.lastToggled = this.model; | ||||
|         this.model.collection.checked = checked; | ||||
|     }, | ||||
|     onChange      : function(e){ | ||||
|         var checked = $(e.target).prop('checked'); | ||||
|         this.$el.parent().toggleClass('selected', checked); | ||||
|         this.model.trigger('backgrid:selected', this.model, checked); | ||||
|     }, | ||||
|     _selectRange  : function(){ | ||||
|         var collection = this.model.collection; | ||||
|         var lastToggled = collection.lastToggled; | ||||
|         var checked = collection.checked; | ||||
|         var currentIndex = collection.indexOf(this.model); | ||||
|         var lastIndex = collection.indexOf(lastToggled); | ||||
|         var low = Math.min(currentIndex, lastIndex); | ||||
|         var high = Math.max(currentIndex, lastIndex); | ||||
|         var range = _.range(low + 1, high); | ||||
|         _.each(range, function(index){ | ||||
|             var model = collection.at(index); | ||||
|             model.trigger('backgrid:select', model, checked); | ||||
|         }); | ||||
|     }); | ||||
|         this.model.collection.lastToggled = undefined; | ||||
|         this.model.collection.checked = undefined; | ||||
|     } | ||||
| }); | ||||
| @@ -1,53 +1,34 @@ | ||||
| 'use strict'; | ||||
| var vent = require('../vent'); | ||||
| var NzbDroneCell = require('./NzbDroneCell'); | ||||
| var CommandController = require('../Commands/CommandController'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'vent', | ||||
|         'Cells/NzbDroneCell', | ||||
|         'Commands/CommandController' | ||||
|     ], function (vent, NzbDroneCell, CommandController) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className: 'series-actions-cell', | ||||
|  | ||||
|             ui: { | ||||
|                 refresh: '.x-refresh' | ||||
|             }, | ||||
|  | ||||
|             events: { | ||||
|                 'click .x-edit'    : '_editSeries', | ||||
|                 'click .x-refresh' : '_refreshSeries' | ||||
|             }, | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|  | ||||
|                 this.$el.html( | ||||
|                     '<i class="icon-refresh x-refresh hidden-xs" title="" data-original-title="Update series info and scan disk"></i> ' + | ||||
|                     '<i class="icon-nd-edit x-edit" title="" data-original-title="Edit Series"></i>' | ||||
|                 ); | ||||
|  | ||||
|                 CommandController.bindToCommand({ | ||||
|                     element: this.$el.find('.x-refresh'), | ||||
|                     command: { | ||||
|                         name     : 'refreshSeries', | ||||
|                         seriesId : this.model.get('id') | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|                 this.delegateEvents(); | ||||
|                 return this; | ||||
|             }, | ||||
|  | ||||
|             _editSeries: function () { | ||||
|                 vent.trigger(vent.Commands.EditSeriesCommand, {series:this.model}); | ||||
|             }, | ||||
|  | ||||
|             _refreshSeries: function () { | ||||
|                 CommandController.Execute('refreshSeries', { | ||||
|                     name    : 'refreshSeries', | ||||
|                     seriesId: this.model.id | ||||
|                 }); | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className      : 'series-actions-cell', | ||||
|     ui             : {refresh : '.x-refresh'}, | ||||
|     events         : { | ||||
|         "click .x-edit"    : '_editSeries', | ||||
|         "click .x-refresh" : '_refreshSeries' | ||||
|     }, | ||||
|     render         : function(){ | ||||
|         this.$el.empty(); | ||||
|         this.$el.html('<i class="icon-refresh x-refresh hidden-xs" title="" data-original-title="Update series info and scan disk"></i> ' + '<i class="icon-nd-edit x-edit" title="" data-original-title="Edit Series"></i>'); | ||||
|         CommandController.bindToCommand({ | ||||
|             element : this.$el.find('.x-refresh'), | ||||
|             command : { | ||||
|                 name     : 'refreshSeries', | ||||
|                 seriesId : this.model.get('id') | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|         this.delegateEvents(); | ||||
|         return this; | ||||
|     }, | ||||
|     _editSeries    : function(){ | ||||
|         vent.trigger(vent.Commands.EditSeriesCommand, {series : this.model}); | ||||
|     }, | ||||
|     _refreshSeries : function(){ | ||||
|         CommandController.Execute('refreshSeries', { | ||||
|             name     : 'refreshSeries', | ||||
|             seriesId : this.model.id | ||||
|         }); | ||||
|     } | ||||
| }); | ||||
| @@ -1,36 +1,26 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function (NzbDroneCell) { | ||||
|         return NzbDroneCell.extend({ | ||||
|             className: 'series-status-cell', | ||||
| var NzbDroneCell = require('./NzbDroneCell'); | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|                 var monitored = this.model.get('monitored'); | ||||
|                 var status = this.model.get('status'); | ||||
|  | ||||
|                 if (status === 'ended') { | ||||
|                     this.$el.html('<i class="icon-stop grid-icon" title="Ended"></i>'); | ||||
|                     this._setStatusWeight(3); | ||||
|                 } | ||||
|  | ||||
|                 else if (!monitored) { | ||||
|                     this.$el.html('<i class="icon-pause grid-icon" title="Not Monitored"></i>'); | ||||
|                     this._setStatusWeight(2); | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     this.$el.html('<i class="icon-play grid-icon" title="Continuing"></i>'); | ||||
|                     this._setStatusWeight(1); | ||||
|                 } | ||||
|  | ||||
|                 return this; | ||||
|             }, | ||||
|  | ||||
|             _setStatusWeight: function (weight) { | ||||
|                 this.model.set('statusWeight', weight, {silent: true}); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className        : 'series-status-cell', | ||||
|     render           : function(){ | ||||
|         this.$el.empty(); | ||||
|         var monitored = this.model.get('monitored'); | ||||
|         var status = this.model.get('status'); | ||||
|         if(status === 'ended') { | ||||
|             this.$el.html('<i class="icon-stop grid-icon" title="Ended"></i>'); | ||||
|             this._setStatusWeight(3); | ||||
|         } | ||||
|         else if(!monitored) { | ||||
|             this.$el.html('<i class="icon-pause grid-icon" title="Not Monitored"></i>'); | ||||
|             this._setStatusWeight(2); | ||||
|         } | ||||
|         else { | ||||
|             this.$el.html('<i class="icon-play grid-icon" title="Continuing"></i>'); | ||||
|             this._setStatusWeight(1); | ||||
|         } | ||||
|         return this; | ||||
|     }, | ||||
|     _setStatusWeight : function(weight){ | ||||
|         this.model.set('statusWeight', weight, {silent : true}); | ||||
|     } | ||||
| }); | ||||
| @@ -1,12 +1,6 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'Cells/TemplatedCell' | ||||
|     ], function (TemplatedCell) { | ||||
|         return TemplatedCell.extend({ | ||||
| var TemplatedCell = require('./TemplatedCell'); | ||||
|  | ||||
|             className: 'series-title-cell', | ||||
|             template : 'Cells/SeriesTitleTemplate' | ||||
|  | ||||
|         }); | ||||
|     }); | ||||
| module.exports = TemplatedCell.extend({ | ||||
|     className : 'series-title-cell', | ||||
|     template  : 'Cells/SeriesTitleTemplate' | ||||
| }); | ||||
| @@ -1,23 +1,14 @@ | ||||
| 'use strict'; | ||||
| var Marionette = require('marionette'); | ||||
| var NzbDroneCell = require('./NzbDroneCell'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function (Marionette, NzbDroneCell) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             render: function () { | ||||
|  | ||||
|                 var templateName = this.column.get('template') || this.template; | ||||
|  | ||||
|                 this.templateFunction = Marionette.TemplateCache.get(templateName); | ||||
|                 var data = this.cellValue.toJSON(); | ||||
|                 var html = this.templateFunction(data); | ||||
|                 this.$el.html(html); | ||||
|  | ||||
|                 this.delegateEvents(); | ||||
|                 return this; | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     render : function(){ | ||||
|         var templateName = this.column.get('template') || this.template; | ||||
|         this.templateFunction = Marionette.TemplateCache.get(templateName); | ||||
|         var data = this.cellValue.toJSON(); | ||||
|         var html = this.templateFunction(data); | ||||
|         this.$el.html(html); | ||||
|         this.delegateEvents(); | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,53 +1,32 @@ | ||||
| 'use strict'; | ||||
| var Backgrid = require('backgrid'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'backgrid' | ||||
|     ], function (Backgrid) { | ||||
|         return Backgrid.Cell.extend({ | ||||
|  | ||||
|             className: 'toggle-cell', | ||||
|  | ||||
|             events: { | ||||
|                 'click': '_onClick' | ||||
|             }, | ||||
|  | ||||
|             _onClick: function () { | ||||
|  | ||||
|                 var self = this; | ||||
|  | ||||
|                 this.$el.tooltip('hide'); | ||||
|  | ||||
|                 var name = this.column.get('name'); | ||||
|                 this.model.set(name, !this.model.get(name)); | ||||
|  | ||||
|                 this.$('i').addClass('icon-spinner icon-spin'); | ||||
|  | ||||
|                 this.model.save().always(function () { | ||||
|                     self.render(); | ||||
|                 }); | ||||
|             }, | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|                 this.$el.html('<i />'); | ||||
|  | ||||
|                 var name = this.column.get('name'); | ||||
|  | ||||
|                 if (this.model.get(name)) { | ||||
|                     this.$('i').addClass(this.column.get('trueClass')); | ||||
|                 } | ||||
|                 else { | ||||
|                     this.$('i').addClass(this.column.get('falseClass')); | ||||
|                 } | ||||
|  | ||||
|                 var tooltip = this.column.get('tooltip'); | ||||
|  | ||||
|                 if (tooltip) { | ||||
|                     this.$('i').attr('title', tooltip); | ||||
|                 } | ||||
|  | ||||
|                 return this; | ||||
|             } | ||||
| module.exports = Backgrid.Cell.extend({ | ||||
|     className : 'toggle-cell', | ||||
|     events    : {"click" : '_onClick'}, | ||||
|     _onClick  : function(){ | ||||
|         var self = this; | ||||
|         this.$el.tooltip('hide'); | ||||
|         var name = this.column.get('name'); | ||||
|         this.model.set(name, !this.model.get(name)); | ||||
|         this.$('i').addClass('icon-spinner icon-spin'); | ||||
|         this.model.save().always(function(){ | ||||
|             self.render(); | ||||
|         }); | ||||
|     }); | ||||
|     }, | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         this.$el.html('<i />'); | ||||
|         var name = this.column.get('name'); | ||||
|         if(this.model.get(name)) { | ||||
|             this.$('i').addClass(this.column.get('trueClass')); | ||||
|         } | ||||
|         else { | ||||
|             this.$('i').addClass(this.column.get('falseClass')); | ||||
|         } | ||||
|         var tooltip = this.column.get('tooltip'); | ||||
|         if(tooltip) { | ||||
|             this.$('i').attr('title', tooltip); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,26 +1,18 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'backbone', | ||||
|         'Commands/CommandModel', | ||||
|         'Mixins/backbone.signalr.mixin' | ||||
|     ], function (Backbone, CommandModel) { | ||||
| var Backbone = require('backbone'); | ||||
| var CommandModel = require('./CommandModel'); | ||||
| require('../Mixins/backbone.signalr.mixin'); | ||||
|  | ||||
|         var CommandCollection = Backbone.Collection.extend({ | ||||
|             url  : window.NzbDrone.ApiRoot + '/command', | ||||
|             model: CommandModel, | ||||
|  | ||||
|             findCommand: function (command) { | ||||
|                 return this.find(function (model) { | ||||
|                     return model.isSameCommand(command); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|         }); | ||||
|  | ||||
|         var collection = new CommandCollection().bindSignalR(); | ||||
|  | ||||
|         collection.fetch(); | ||||
|  | ||||
|         return collection; | ||||
| module.exports = (function(){ | ||||
|     var CommandCollection = Backbone.Collection.extend({ | ||||
|         url         : window.NzbDrone.ApiRoot + '/command', | ||||
|         model       : CommandModel, | ||||
|         findCommand : function(command){ | ||||
|             return this.find(function(model){ | ||||
|                 return model.isSameCommand(command); | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
|     var collection = new CommandCollection().bindSignalR(); | ||||
|     collection.fetch(); | ||||
|     return collection; | ||||
| }).call(this); | ||||
| @@ -1,98 +1,75 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'vent', | ||||
|         'Commands/CommandModel', | ||||
|         'Commands/CommandCollection', | ||||
|         'Commands/CommandMessengerCollectionView', | ||||
|         'underscore', | ||||
|         'moment', | ||||
|         'Shared/Messenger', | ||||
|         'jQuery/jquery.spin' | ||||
|     ], function (vent, CommandModel, CommandCollection, CommandMessengerCollectionView, _, moment, Messenger) { | ||||
| var vent = require('../vent'); | ||||
| var CommandModel = require('./CommandModel'); | ||||
| var CommandCollection = require('./CommandCollection'); | ||||
| var CommandMessengerCollectionView = require('./CommandMessengerCollectionView'); | ||||
| var _ = require('underscore'); | ||||
| var moment = require('moment'); | ||||
| var Messenger = require('../Shared/Messenger'); | ||||
| require('../jQuery/jquery.spin'); | ||||
|  | ||||
|  | ||||
|         CommandMessengerCollectionView.render(); | ||||
|  | ||||
|         var singleton = function () { | ||||
|  | ||||
|             return { | ||||
|  | ||||
|                 _lastCommand: {}, | ||||
|  | ||||
|                 Execute: function (name, properties) { | ||||
|  | ||||
|                     var attr = _.extend({name: name.toLocaleLowerCase()}, properties); | ||||
|                     var commandModel = new CommandModel(attr); | ||||
|  | ||||
|                     if (this._lastCommand.command && this._lastCommand.command.isSameCommand(attr) && moment().add('seconds', -5).isBefore(this._lastCommand.time)) { | ||||
|  | ||||
|                         Messenger.show({ | ||||
|                             message: 'Please wait at least 5 seconds before running this command again', | ||||
|                             hideAfter: 5, | ||||
|                             type: 'error' | ||||
|                         }); | ||||
|  | ||||
|                         return this._lastCommand.promise; | ||||
|                     } | ||||
|  | ||||
|                     var promise = commandModel.save().success(function () { | ||||
|                         CommandCollection.add(commandModel); | ||||
| module.exports = (function(){ | ||||
|     CommandMessengerCollectionView.render(); | ||||
|     var singleton = function(){ | ||||
|         return { | ||||
|             _lastCommand        : {}, | ||||
|             Execute             : function(name, properties){ | ||||
|                 var attr = _.extend({name : name.toLocaleLowerCase()}, properties); | ||||
|                 var commandModel = new CommandModel(attr); | ||||
|                 if(this._lastCommand.command && this._lastCommand.command.isSameCommand(attr) && moment().add('seconds', -5).isBefore(this._lastCommand.time)) { | ||||
|                     Messenger.show({ | ||||
|                         message   : 'Please wait at least 5 seconds before running this command again', | ||||
|                         hideAfter : 5, | ||||
|                         type      : 'error' | ||||
|                     }); | ||||
|  | ||||
|                     this._lastCommand = { | ||||
|                         command : commandModel, | ||||
|                         promise : promise, | ||||
|                         time    : moment() | ||||
|                     }; | ||||
|  | ||||
|                     return promise; | ||||
|                 }, | ||||
|  | ||||
|                 bindToCommand: function (options) { | ||||
|  | ||||
|                     var self = this; | ||||
|                     var existingCommand = CommandCollection.findCommand(options.command); | ||||
|  | ||||
|                     if (existingCommand) { | ||||
|                         this._bindToCommandModel.call(this, existingCommand, options); | ||||
|                     } | ||||
|  | ||||
|                     CommandCollection.bind('add', function (model) { | ||||
|                         if (model.isSameCommand(options.command)) { | ||||
|                             self._bindToCommandModel.call(self, model, options); | ||||
|                         } | ||||
|                     }); | ||||
|  | ||||
|                     CommandCollection.bind('sync', function () { | ||||
|                         var command = CommandCollection.findCommand(options.command); | ||||
|                         if (command) { | ||||
|                             self._bindToCommandModel.call(self, command, options); | ||||
|                         } | ||||
|                     }); | ||||
|                 }, | ||||
|  | ||||
|                 _bindToCommandModel: function bindToCommand(model, options) { | ||||
|  | ||||
|                     if (!model.isActive()) { | ||||
|                         options.element.stopSpin(); | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     model.bind('change:state', function (model) { | ||||
|                         if (!model.isActive()) { | ||||
|                             options.element.stopSpin(); | ||||
|  | ||||
|                             if (model.isComplete()) { | ||||
|                                 vent.trigger(vent.Events.CommandComplete, { command: model, model: options.model }); | ||||
|                             } | ||||
|                         } | ||||
|                     }); | ||||
|  | ||||
|                     options.element.startSpin(); | ||||
|                     return this._lastCommand.promise; | ||||
|                 } | ||||
|             }; | ||||
|                 var promise = commandModel.save().success(function(){ | ||||
|                     CommandCollection.add(commandModel); | ||||
|                 }); | ||||
|                 this._lastCommand = { | ||||
|                     command : commandModel, | ||||
|                     promise : promise, | ||||
|                     time    : moment() | ||||
|                 }; | ||||
|                 return promise; | ||||
|             }, | ||||
|             bindToCommand       : function(options){ | ||||
|                 var self = this; | ||||
|                 var existingCommand = CommandCollection.findCommand(options.command); | ||||
|                 if(existingCommand) { | ||||
|                     this._bindToCommandModel.call(this, existingCommand, options); | ||||
|                 } | ||||
|                 CommandCollection.bind('add', function(model){ | ||||
|                     if(model.isSameCommand(options.command)) { | ||||
|                         self._bindToCommandModel.call(self, model, options); | ||||
|                     } | ||||
|                 }); | ||||
|                 CommandCollection.bind('sync', function(){ | ||||
|                     var command = CommandCollection.findCommand(options.command); | ||||
|                     if(command) { | ||||
|                         self._bindToCommandModel.call(self, command, options); | ||||
|                     } | ||||
|                 }); | ||||
|             }, | ||||
|             _bindToCommandModel : function bindToCommand (model, options){ | ||||
|                 if(!model.isActive()) { | ||||
|                     options.element.stopSpin(); | ||||
|                     return; | ||||
|                 } | ||||
|                 model.bind('change:state', function(model){ | ||||
|                     if(!model.isActive()) { | ||||
|                         options.element.stopSpin(); | ||||
|                         if(model.isComplete()) { | ||||
|                             vent.trigger(vent.Events.CommandComplete, { | ||||
|                                 command : model, | ||||
|                                 model   : options.model | ||||
|                             }); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|                 options.element.startSpin(); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         return singleton(); | ||||
|     }); | ||||
|     }; | ||||
|     return singleton(); | ||||
| }).call(this); | ||||
| @@ -1,14 +1,8 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'Commands/CommandCollection', | ||||
|         'Commands/CommandMessengerItemView' | ||||
|     ], function (Marionette, commandCollection, CommandMessengerItemView) { | ||||
| var Marionette = require('marionette'); | ||||
| var commandCollection = require('./CommandCollection'); | ||||
| var CommandMessengerItemView = require('./CommandMessengerItemView'); | ||||
|  | ||||
|         var CollectionView = Marionette.CollectionView.extend({ | ||||
|             itemView: CommandMessengerItemView | ||||
|         }); | ||||
|  | ||||
|         return new CollectionView({collection: commandCollection}); | ||||
|     }); | ||||
| module.exports = (function(){ | ||||
|     var CollectionView = Marionette.CollectionView.extend({itemView : CommandMessengerItemView}); | ||||
|     return new CollectionView({collection : commandCollection}); | ||||
| }).call(this); | ||||
| @@ -1,51 +1,37 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'Shared/Messenger' | ||||
|     ], function ( Marionette, Messenger) { | ||||
| var Marionette = require('marionette'); | ||||
| var Messenger = require('../Shared/Messenger'); | ||||
|  | ||||
|         return Marionette.ItemView.extend({ | ||||
|  | ||||
|             initialize: function () { | ||||
|                 this.listenTo(this.model, 'change', this.render); | ||||
|             }, | ||||
|  | ||||
|             render: function () { | ||||
|                 if (!this.model.get('message') || !this.model.get('sendUpdatesToClient')) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 var message = { | ||||
|                     type     : 'info', | ||||
|                     message  : '[{0}] {1}'.format(this.model.get('name'), this.model.get('message')), | ||||
|                     id       : this.model.id, | ||||
|                     hideAfter: 0 | ||||
|                 }; | ||||
|  | ||||
|                 switch (this.model.get('state')) { | ||||
|                     case 'completed': | ||||
|                         message.hideAfter = 4; | ||||
|                         break; | ||||
|                     case 'failed': | ||||
|                         message.hideAfter = 4; | ||||
|                         message.type = 'error'; | ||||
|                         break; | ||||
|                     default : | ||||
|                         message.hideAfter = 0; | ||||
|                 } | ||||
|  | ||||
|                 if (this.messenger) { | ||||
|                     this.messenger.update(message); | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     this.messenger = Messenger.show(message); | ||||
|                 } | ||||
|  | ||||
|                 console.log(message.message); | ||||
|             } | ||||
|  | ||||
|         }); | ||||
|  | ||||
|     }); | ||||
| module.exports = Marionette.ItemView.extend({ | ||||
|     initialize : function(){ | ||||
|         this.listenTo(this.model, 'change', this.render); | ||||
|     }, | ||||
|     render     : function(){ | ||||
|         if(!this.model.get('message') || !this.model.get('sendUpdatesToClient')) { | ||||
|             return; | ||||
|         } | ||||
|         var message = { | ||||
|             type      : 'info', | ||||
|             message   : '[{0}] {1}'.format(this.model.get('name'), this.model.get('message')), | ||||
|             id        : this.model.id, | ||||
|             hideAfter : 0 | ||||
|         }; | ||||
|         switch (this.model.get('state')) { | ||||
|             case 'completed': | ||||
|                 message.hideAfter = 4; | ||||
|                 break; | ||||
|             case 'failed': | ||||
|                 message.hideAfter = 4; | ||||
|                 message.type = 'error'; | ||||
|                 break; | ||||
|             default: | ||||
|                 message.hideAfter = 0; | ||||
|         } | ||||
|         if(this.messenger) { | ||||
|             this.messenger.update(message); | ||||
|         } | ||||
|         else { | ||||
|             this.messenger = Messenger.show(message); | ||||
|         } | ||||
|         console.log(message.message); | ||||
|     } | ||||
| }); | ||||
| @@ -1,46 +1,34 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'underscore', | ||||
|         'backbone' | ||||
|     ], function (_, Backbone) { | ||||
|         return Backbone.Model.extend({ | ||||
|             url: window.NzbDrone.ApiRoot + '/command', | ||||
| var _ = require('underscore'); | ||||
| var Backbone = require('backbone'); | ||||
|  | ||||
|             parse: function (response) { | ||||
|                 response.name = response.name.toLocaleLowerCase(); | ||||
|                 return response; | ||||
|             }, | ||||
|  | ||||
|             isSameCommand: function (command) { | ||||
|  | ||||
|                 if (command.name.toLocaleLowerCase() !== this.get('name').toLocaleLowerCase()) { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 for (var key in command) { | ||||
|                     if (key !== 'name') { | ||||
|                         if (Array.isArray(command[key])) { | ||||
|                             if (_.difference(command[key], this.get(key)).length > 0) { | ||||
|                                 return false; | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
|                         else if (command[key] !== this.get(key)) { | ||||
|                             return false; | ||||
|                         } | ||||
| module.exports = Backbone.Model.extend({ | ||||
|     url           : window.NzbDrone.ApiRoot + '/command', | ||||
|     parse         : function(response){ | ||||
|         response.name = response.name.toLocaleLowerCase(); | ||||
|         return response; | ||||
|     }, | ||||
|     isSameCommand : function(command){ | ||||
|         if(command.name.toLocaleLowerCase() !== this.get('name').toLocaleLowerCase()) { | ||||
|             return false; | ||||
|         } | ||||
|         for (var key in command) { | ||||
|             if(key !== 'name') { | ||||
|                 if(Array.isArray(command[key])) { | ||||
|                     if(_.difference(command[key], this.get(key)).length > 0) { | ||||
|                         return false; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 return true; | ||||
|             }, | ||||
|  | ||||
|             isActive: function () { | ||||
|                 return this.get('state') !== 'completed' && this.get('state') !== 'failed'; | ||||
|             }, | ||||
|  | ||||
|             isComplete: function () { | ||||
|                 return this.get('state') === 'completed'; | ||||
|                 else if(command[key] !== this.get(key)) { | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|         } | ||||
|         return true; | ||||
|     }, | ||||
|     isActive      : function(){ | ||||
|         return this.get('state') !== 'completed' && this.get('state') !== 'failed'; | ||||
|     }, | ||||
|     isComplete    : function(){ | ||||
|         return this.get('state') === 'completed'; | ||||
|     } | ||||
| }); | ||||
| @@ -1,77 +1,51 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'Shared/NzbDroneController', | ||||
|         'AppLayout', | ||||
|         'marionette', | ||||
|         'Activity/ActivityLayout', | ||||
|         'Settings/SettingsLayout', | ||||
|         'AddSeries/AddSeriesLayout', | ||||
|         'Wanted/WantedLayout', | ||||
|         'Calendar/CalendarLayout', | ||||
|         'Release/ReleaseLayout', | ||||
|         'System/SystemLayout', | ||||
|         'SeasonPass/SeasonPassLayout', | ||||
|         'Series/Editor/SeriesEditorLayout' | ||||
|     ], function (NzbDroneController, | ||||
|                  AppLayout, | ||||
|                  Marionette, | ||||
|                  ActivityLayout, | ||||
|                  SettingsLayout, | ||||
|                  AddSeriesLayout, | ||||
|                  WantedLayout, | ||||
|                  CalendarLayout, | ||||
|                  ReleaseLayout, | ||||
|                  SystemLayout, | ||||
|                  SeasonPassLayout, | ||||
|                  SeriesEditorLayout) { | ||||
|         return NzbDroneController.extend({ | ||||
| var NzbDroneController = require('./Shared/NzbDroneController'); | ||||
| var AppLayout = require('./AppLayout'); | ||||
| var Marionette = require('marionette'); | ||||
| var ActivityLayout = require('./Activity/ActivityLayout'); | ||||
| var SettingsLayout = require('./Settings/SettingsLayout'); | ||||
| var AddSeriesLayout = require('./AddSeries/AddSeriesLayout'); | ||||
| var WantedLayout = require('./Wanted/WantedLayout'); | ||||
| var CalendarLayout = require('./Calendar/CalendarLayout'); | ||||
| var ReleaseLayout = require('./Release/ReleaseLayout'); | ||||
| var SystemLayout = require('./System/SystemLayout'); | ||||
| var SeasonPassLayout = require('./SeasonPass/SeasonPassLayout'); | ||||
| var SeriesEditorLayout = require('./Series/Editor/SeriesEditorLayout'); | ||||
|  | ||||
|             addSeries: function (action) { | ||||
|                 this.setTitle('Add Series'); | ||||
|                 this.showMainRegion(new AddSeriesLayout({action: action})); | ||||
|             }, | ||||
|  | ||||
|             calendar: function () { | ||||
|                 this.setTitle('Calendar'); | ||||
|                 this.showMainRegion(new CalendarLayout()); | ||||
|             }, | ||||
|  | ||||
|             settings: function (action) { | ||||
|                 this.setTitle('Settings'); | ||||
|                 this.showMainRegion(new SettingsLayout({ action: action })); | ||||
|             }, | ||||
|  | ||||
|             wanted: function (action) { | ||||
|                 this.setTitle('Wanted'); | ||||
|  | ||||
|                 this.showMainRegion(new WantedLayout({ action: action })); | ||||
|             }, | ||||
|  | ||||
|             activity: function (action) { | ||||
|                 this.setTitle('Activity'); | ||||
|  | ||||
|                 this.showMainRegion(new ActivityLayout({ action: action })); | ||||
|             }, | ||||
|  | ||||
|             rss: function () { | ||||
|                 this.setTitle('RSS'); | ||||
|                 this.showMainRegion(new ReleaseLayout()); | ||||
|             }, | ||||
|  | ||||
|             system: function (action) { | ||||
|                 this.setTitle('System'); | ||||
|                 this.showMainRegion(new SystemLayout({ action: action })); | ||||
|             }, | ||||
|  | ||||
|             seasonPass: function () { | ||||
|                 this.setTitle('Season Pass'); | ||||
|                 this.showMainRegion(new SeasonPassLayout()); | ||||
|             }, | ||||
|  | ||||
|             seriesEditor: function () { | ||||
|                 this.setTitle('Series Editor'); | ||||
|                 this.showMainRegion(new SeriesEditorLayout()); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = NzbDroneController.extend({ | ||||
|     addSeries    : function(action){ | ||||
|         this.setTitle('Add Series'); | ||||
|         this.showMainRegion(new AddSeriesLayout({action : action})); | ||||
|     }, | ||||
|     calendar     : function(){ | ||||
|         this.setTitle('Calendar'); | ||||
|         this.showMainRegion(new CalendarLayout()); | ||||
|     }, | ||||
|     settings     : function(action){ | ||||
|         this.setTitle('Settings'); | ||||
|         this.showMainRegion(new SettingsLayout({action : action})); | ||||
|     }, | ||||
|     wanted       : function(action){ | ||||
|         this.setTitle('Wanted'); | ||||
|         this.showMainRegion(new WantedLayout({action : action})); | ||||
|     }, | ||||
|     activity     : function(action){ | ||||
|         this.setTitle('Activity'); | ||||
|         this.showMainRegion(new ActivityLayout({action : action})); | ||||
|     }, | ||||
|     rss          : function(){ | ||||
|         this.setTitle('RSS'); | ||||
|         this.showMainRegion(new ReleaseLayout()); | ||||
|     }, | ||||
|     system       : function(action){ | ||||
|         this.setTitle('System'); | ||||
|         this.showMainRegion(new SystemLayout({action : action})); | ||||
|     }, | ||||
|     seasonPass   : function(){ | ||||
|         this.setTitle('Season Pass'); | ||||
|         this.showMainRegion(new SeasonPassLayout()); | ||||
|     }, | ||||
|     seriesEditor : function(){ | ||||
|         this.setTitle('Series Editor'); | ||||
|         this.showMainRegion(new SeriesEditorLayout()); | ||||
|     } | ||||
| }); | ||||
| @@ -1,41 +1,25 @@ | ||||
| 'use strict'; | ||||
| var $ = require('jquery'); | ||||
| var vent = require('../../vent'); | ||||
| var Marionette = require('marionette'); | ||||
| var NzbDroneCell = require('../../Cells/NzbDroneCell'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'jquery', | ||||
|         'vent', | ||||
|         'marionette', | ||||
|         'Cells/NzbDroneCell' | ||||
|     ], function ($, vent, Marionette, NzbDroneCell) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className: 'episode-actions-cell', | ||||
|  | ||||
|             events: { | ||||
|                 'click .x-failed' : '_markAsFailed' | ||||
|             }, | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|  | ||||
|                 if (this.model.get('eventType') === 'grabbed') { | ||||
|                     this.$el.html('<i class="icon-nd-delete x-failed" title="Mark download as failed"></i>'); | ||||
|                 } | ||||
|  | ||||
|                 return this; | ||||
|             }, | ||||
|  | ||||
|             _markAsFailed: function () { | ||||
|                 var url = window.NzbDrone.ApiRoot + '/history/failed'; | ||||
|                 var data = { | ||||
|                     id: this.model.get('id') | ||||
|                 }; | ||||
|  | ||||
|                 $.ajax({ | ||||
|                     url: url, | ||||
|                     type: 'POST', | ||||
|                     data: data | ||||
|                 }); | ||||
|             } | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className     : 'episode-actions-cell', | ||||
|     events        : {"click .x-failed" : '_markAsFailed'}, | ||||
|     render        : function(){ | ||||
|         this.$el.empty(); | ||||
|         if(this.model.get('eventType') === 'grabbed') { | ||||
|             this.$el.html('<i class="icon-nd-delete x-failed" title="Mark download as failed"></i>'); | ||||
|         } | ||||
|         return this; | ||||
|     }, | ||||
|     _markAsFailed : function(){ | ||||
|         var url = window.NzbDrone.ApiRoot + '/history/failed'; | ||||
|         var data = {id : this.model.get('id')}; | ||||
|         $.ajax({ | ||||
|             url  : url, | ||||
|             type : 'POST', | ||||
|             data : data | ||||
|         }); | ||||
|     }); | ||||
|     } | ||||
| }); | ||||
| @@ -1,35 +1,24 @@ | ||||
| 'use strict'; | ||||
| var $ = require('jquery'); | ||||
| var vent = require('../../vent'); | ||||
| var Marionette = require('marionette'); | ||||
| var NzbDroneCell = require('../../Cells/NzbDroneCell'); | ||||
| var HistoryDetailsView = require('../../Activity/History/Details/HistoryDetailsView'); | ||||
| require('bootstrap'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'jquery', | ||||
|         'vent', | ||||
|         'marionette', | ||||
|         'Cells/NzbDroneCell', | ||||
|         'Activity/History/Details/HistoryDetailsView', | ||||
|         'bootstrap' | ||||
|     ], function ($, vent, Marionette, NzbDroneCell, HistoryDetailsView) { | ||||
|         return NzbDroneCell.extend({ | ||||
|  | ||||
|             className: 'episode-activity-details-cell', | ||||
|  | ||||
|  | ||||
|             render: function () { | ||||
|                 this.$el.empty(); | ||||
|                 this.$el.html('<i class="icon-info-sign"></i>'); | ||||
|  | ||||
|                 var html = new HistoryDetailsView({ model: this.model }).render().$el; | ||||
|  | ||||
|                 this.$el.popover({ | ||||
|                     content  : html, | ||||
|                     html     : true, | ||||
|                     trigger  : 'hover', | ||||
|                     title    : 'Details', | ||||
|                     placement: 'left', | ||||
|                     container: this.$el | ||||
|                 }); | ||||
|  | ||||
|                 return this; | ||||
|             } | ||||
| module.exports = NzbDroneCell.extend({ | ||||
|     className : 'episode-activity-details-cell', | ||||
|     render    : function(){ | ||||
|         this.$el.empty(); | ||||
|         this.$el.html('<i class="icon-info-sign"></i>'); | ||||
|         var html = new HistoryDetailsView({model : this.model}).render().$el; | ||||
|         this.$el.popover({ | ||||
|             content   : html, | ||||
|             html      : true, | ||||
|             trigger   : 'hover', | ||||
|             title     : 'Details', | ||||
|             placement : 'left', | ||||
|             container : this.$el | ||||
|         }); | ||||
|     }); | ||||
|         return this; | ||||
|     } | ||||
| }); | ||||
| @@ -1,96 +1,68 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'backgrid', | ||||
|         'Activity/History/HistoryCollection', | ||||
|         'Cells/EventTypeCell', | ||||
|         'Cells/QualityCell', | ||||
|         'Cells/RelativeDateCell', | ||||
|         'Episode/Activity/EpisodeActivityActionsCell', | ||||
|         'Episode/Activity/EpisodeActivityDetailsCell', | ||||
|         'Episode/Activity/NoActivityView', | ||||
|         'Shared/LoadingView' | ||||
|     ], function (Marionette, | ||||
|                  Backgrid, | ||||
|                  HistoryCollection, | ||||
|                  EventTypeCell, | ||||
|                  QualityCell, | ||||
|                  RelativeDateCell, | ||||
|                  EpisodeActivityActionsCell, | ||||
|                  EpisodeActivityDetailsCell, | ||||
|                  NoActivityView, | ||||
|                  LoadingView) { | ||||
| var Marionette = require('marionette'); | ||||
| var Backgrid = require('backgrid'); | ||||
| var HistoryCollection = require('../../Activity/History/HistoryCollection'); | ||||
| var EventTypeCell = require('../../Cells/EventTypeCell'); | ||||
| var QualityCell = require('../../Cells/QualityCell'); | ||||
| var RelativeDateCell = require('../../Cells/RelativeDateCell'); | ||||
| var EpisodeActivityActionsCell = require('./EpisodeActivityActionsCell'); | ||||
| var EpisodeActivityDetailsCell = require('./EpisodeActivityDetailsCell'); | ||||
| var NoActivityView = require('./NoActivityView'); | ||||
| var LoadingView = require('../../Shared/LoadingView'); | ||||
|  | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'Episode/Activity/EpisodeActivityLayoutTemplate', | ||||
|  | ||||
|             regions: { | ||||
|                 activityTable: '.activity-table' | ||||
|             }, | ||||
|  | ||||
|             columns: | ||||
|                 [ | ||||
|                     { | ||||
|                         name     : 'eventType', | ||||
|                         label    : '', | ||||
|                         cell     : EventTypeCell, | ||||
|                         cellValue: 'this' | ||||
|                     }, | ||||
|                     { | ||||
|                         name : 'sourceTitle', | ||||
|                         label: 'Source Title', | ||||
|                         cell : 'string' | ||||
|                     }, | ||||
|                     { | ||||
|                         name : 'quality', | ||||
|                         label: 'Quality', | ||||
|                         cell : QualityCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name : 'date', | ||||
|                         label: 'Date', | ||||
|                         cell : RelativeDateCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name    : 'this', | ||||
|                         label   : '', | ||||
|                         cell    : EpisodeActivityDetailsCell, | ||||
|                         sortable: false | ||||
|                     }, | ||||
|                     { | ||||
|                         name    : 'this', | ||||
|                         label   : '', | ||||
|                         cell    : EpisodeActivityActionsCell, | ||||
|                         sortable: false | ||||
|                     } | ||||
|                 ], | ||||
|  | ||||
|             initialize: function (options) { | ||||
|                 this.model = options.model; | ||||
|                 this.series = options.series; | ||||
|  | ||||
|                 this.collection = new HistoryCollection({ episodeId: this.model.id, tableName: 'episodeActivity' }); | ||||
|                 this.collection.fetch(); | ||||
|                 this.listenTo(this.collection, 'sync', this._showTable); | ||||
|             }, | ||||
|  | ||||
|             onRender: function () { | ||||
|                 this.activityTable.show(new LoadingView()); | ||||
|             }, | ||||
|  | ||||
|             _showTable: function () { | ||||
|                 if (this.collection.any()) { | ||||
|                     this.activityTable.show(new Backgrid.Grid({ | ||||
|                         collection: this.collection, | ||||
|                         columns   : this.columns, | ||||
|                         className : 'table table-hover table-condensed' | ||||
|                     })); | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     this.activityTable.show(new NoActivityView()); | ||||
|                 } | ||||
|             } | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template   : 'Episode/Activity/EpisodeActivityLayoutTemplate', | ||||
|     regions    : {activityTable : '.activity-table'}, | ||||
|     columns    : [{ | ||||
|         name      : 'eventType', | ||||
|         label     : '', | ||||
|         cell      : EventTypeCell, | ||||
|         cellValue : 'this' | ||||
|     }, { | ||||
|         name  : 'sourceTitle', | ||||
|         label : 'Source Title', | ||||
|         cell  : 'string' | ||||
|     }, { | ||||
|         name  : 'quality', | ||||
|         label : 'Quality', | ||||
|         cell  : QualityCell | ||||
|     }, { | ||||
|         name  : 'date', | ||||
|         label : 'Date', | ||||
|         cell  : RelativeDateCell | ||||
|     }, { | ||||
|         name     : 'this', | ||||
|         label    : '', | ||||
|         cell     : EpisodeActivityDetailsCell, | ||||
|         sortable : false | ||||
|     }, { | ||||
|         name     : 'this', | ||||
|         label    : '', | ||||
|         cell     : EpisodeActivityActionsCell, | ||||
|         sortable : false | ||||
|     }], | ||||
|     initialize : function(options){ | ||||
|         this.model = options.model; | ||||
|         this.series = options.series; | ||||
|         this.collection = new HistoryCollection({ | ||||
|             episodeId : this.model.id, | ||||
|             tableName : 'episodeActivity' | ||||
|         }); | ||||
|     }); | ||||
|         this.collection.fetch(); | ||||
|         this.listenTo(this.collection, 'sync', this._showTable); | ||||
|     }, | ||||
|     onRender   : function(){ | ||||
|         this.activityTable.show(new LoadingView()); | ||||
|     }, | ||||
|     _showTable : function(){ | ||||
|         if(this.collection.any()) { | ||||
|             this.activityTable.show(new Backgrid.Grid({ | ||||
|                 collection : this.collection, | ||||
|                 columns    : this.columns, | ||||
|                 className  : 'table table-hover table-condensed' | ||||
|             })); | ||||
|         } | ||||
|         else { | ||||
|             this.activityTable.show(new NoActivityView()); | ||||
|         } | ||||
|     } | ||||
| }); | ||||
| @@ -1,11 +1,3 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette' | ||||
|     ], function (Marionette) { | ||||
| var Marionette = require('marionette'); | ||||
|  | ||||
|         return Marionette.ItemView.extend({ | ||||
|             template: 'Episode/Activity/NoActivityViewTemplate' | ||||
|         }); | ||||
|  | ||||
|     }); | ||||
| module.exports = Marionette.ItemView.extend({template : 'Episode/Activity/NoActivityViewTemplate'}); | ||||
| @@ -1,130 +1,104 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'Episode/Summary/EpisodeSummaryLayout', | ||||
|         'Episode/Search/EpisodeSearchLayout', | ||||
|         'Episode/Activity/EpisodeActivityLayout', | ||||
|         'Series/SeriesCollection', | ||||
|         'Shared/Messenger' | ||||
|     ], function (Marionette, SummaryLayout, SearchLayout, EpisodeActivityLayout, SeriesCollection, Messenger) { | ||||
| var Marionette = require('marionette'); | ||||
| var SummaryLayout = require('./Summary/EpisodeSummaryLayout'); | ||||
| var SearchLayout = require('./Search/EpisodeSearchLayout'); | ||||
| var EpisodeActivityLayout = require('./Activity/EpisodeActivityLayout'); | ||||
| var SeriesCollection = require('../Series/SeriesCollection'); | ||||
| var Messenger = require('../Shared/Messenger'); | ||||
|  | ||||
|         return Marionette.Layout.extend({ | ||||
|             className : 'modal-lg', | ||||
|             template  : 'Episode/EpisodeDetailsLayoutTemplate', | ||||
|  | ||||
|             regions: { | ||||
|                 summary : '#episode-summary', | ||||
|                 activity: '#episode-activity', | ||||
|                 search  : '#episode-search' | ||||
|             }, | ||||
|  | ||||
|             ui: { | ||||
|                 summary  : '.x-episode-summary', | ||||
|                 activity : '.x-episode-activity', | ||||
|                 search   : '.x-episode-search', | ||||
|                 monitored: '.x-episode-monitored' | ||||
|             }, | ||||
|  | ||||
|             events: { | ||||
|  | ||||
|                 'click .x-episode-summary'  : '_showSummary', | ||||
|                 'click .x-episode-activity' : '_showActivity', | ||||
|                 'click .x-episode-search'   : '_showSearch', | ||||
|                 'click .x-episode-monitored': '_toggleMonitored' | ||||
|             }, | ||||
|  | ||||
|             templateHelpers: {}, | ||||
|  | ||||
|             initialize: function (options) { | ||||
|                 this.templateHelpers.hideSeriesLink = options.hideSeriesLink; | ||||
|  | ||||
|                 this.series = SeriesCollection.get(this.model.get('seriesId')); | ||||
|                 this.templateHelpers.series = this.series.toJSON(); | ||||
|                 this.openingTab = options.openingTab || 'summary'; | ||||
|  | ||||
|                 this.listenTo(this.model, 'sync', this._setMonitoredState); | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 this.searchLayout = new SearchLayout({ model: this.model }); | ||||
|  | ||||
|                 if (this.openingTab === 'search') { | ||||
|                     this.searchLayout.startManualSearch = true; | ||||
|                     this._showSearch(); | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     this._showSummary(); | ||||
|                 } | ||||
|  | ||||
|                 this._setMonitoredState(); | ||||
|  | ||||
|                 if (this.series.get('monitored')) { | ||||
|                     this.$el.removeClass('series-not-monitored'); | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     this.$el.addClass('series-not-monitored'); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             _showSummary: function (e) { | ||||
|                 if (e) { | ||||
|                     e.preventDefault(); | ||||
|                 } | ||||
|  | ||||
|                 this.ui.summary.tab('show'); | ||||
|                 this.summary.show(new SummaryLayout({model: this.model, series: this.series})); | ||||
|             }, | ||||
|  | ||||
|             _showActivity: function (e) { | ||||
|                 if (e) { | ||||
|                     e.preventDefault(); | ||||
|                 } | ||||
|  | ||||
|                 this.ui.activity.tab('show'); | ||||
|                 this.activity.show(new EpisodeActivityLayout({model: this.model, series: this.series})); | ||||
|             }, | ||||
|  | ||||
|             _showSearch: function (e) { | ||||
|                 if (e) { | ||||
|                     e.preventDefault(); | ||||
|                 } | ||||
|  | ||||
|                 this.ui.search.tab('show'); | ||||
|                 this.search.show(this.searchLayout); | ||||
|             }, | ||||
|  | ||||
|             _toggleMonitored: 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), { silent: true }); | ||||
|  | ||||
|                 this.ui.monitored.addClass('icon-spinner icon-spin'); | ||||
|                 this.model.save(); | ||||
|             }, | ||||
|  | ||||
|             _setMonitoredState: function () { | ||||
|                 this.ui.monitored.removeClass('icon-spin icon-spinner'); | ||||
|  | ||||
|                 if (this.model.get('monitored')) { | ||||
|                     this.ui.monitored.addClass('icon-bookmark'); | ||||
|                     this.ui.monitored.removeClass('icon-bookmark-empty'); | ||||
|                 } | ||||
|                 else { | ||||
|                     this.ui.monitored.addClass('icon-bookmark-empty'); | ||||
|                     this.ui.monitored.removeClass('icon-bookmark'); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     className          : 'modal-lg', | ||||
|     template           : 'Episode/EpisodeDetailsLayoutTemplate', | ||||
|     regions            : { | ||||
|         summary  : '#episode-summary', | ||||
|         activity : '#episode-activity', | ||||
|         search   : '#episode-search' | ||||
|     }, | ||||
|     ui                 : { | ||||
|         summary   : '.x-episode-summary', | ||||
|         activity  : '.x-episode-activity', | ||||
|         search    : '.x-episode-search', | ||||
|         monitored : '.x-episode-monitored' | ||||
|     }, | ||||
|     events             : { | ||||
|         "click .x-episode-summary"   : '_showSummary', | ||||
|         "click .x-episode-activity"  : '_showActivity', | ||||
|         "click .x-episode-search"    : '_showSearch', | ||||
|         "click .x-episode-monitored" : '_toggleMonitored' | ||||
|     }, | ||||
|     templateHelpers    : {}, | ||||
|     initialize         : function(options){ | ||||
|         this.templateHelpers.hideSeriesLink = options.hideSeriesLink; | ||||
|         this.series = SeriesCollection.get(this.model.get('seriesId')); | ||||
|         this.templateHelpers.series = this.series.toJSON(); | ||||
|         this.openingTab = options.openingTab || 'summary'; | ||||
|         this.listenTo(this.model, 'sync', this._setMonitoredState); | ||||
|     }, | ||||
|     onShow             : function(){ | ||||
|         this.searchLayout = new SearchLayout({model : this.model}); | ||||
|         if(this.openingTab === 'search') { | ||||
|             this.searchLayout.startManualSearch = true; | ||||
|             this._showSearch(); | ||||
|         } | ||||
|         else { | ||||
|             this._showSummary(); | ||||
|         } | ||||
|         this._setMonitoredState(); | ||||
|         if(this.series.get('monitored')) { | ||||
|             this.$el.removeClass('series-not-monitored'); | ||||
|         } | ||||
|         else { | ||||
|             this.$el.addClass('series-not-monitored'); | ||||
|         } | ||||
|     }, | ||||
|     _showSummary       : function(e){ | ||||
|         if(e) { | ||||
|             e.preventDefault(); | ||||
|         } | ||||
|         this.ui.summary.tab('show'); | ||||
|         this.summary.show(new SummaryLayout({ | ||||
|             model  : this.model, | ||||
|             series : this.series | ||||
|         })); | ||||
|     }, | ||||
|     _showActivity      : function(e){ | ||||
|         if(e) { | ||||
|             e.preventDefault(); | ||||
|         } | ||||
|         this.ui.activity.tab('show'); | ||||
|         this.activity.show(new EpisodeActivityLayout({ | ||||
|             model  : this.model, | ||||
|             series : this.series | ||||
|         })); | ||||
|     }, | ||||
|     _showSearch        : function(e){ | ||||
|         if(e) { | ||||
|             e.preventDefault(); | ||||
|         } | ||||
|         this.ui.search.tab('show'); | ||||
|         this.search.show(this.searchLayout); | ||||
|     }, | ||||
|     _toggleMonitored   : 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), {silent : true}); | ||||
|         this.ui.monitored.addClass('icon-spinner icon-spin'); | ||||
|         this.model.save(); | ||||
|     }, | ||||
|     _setMonitoredState : function(){ | ||||
|         this.ui.monitored.removeClass('icon-spin icon-spinner'); | ||||
|         if(this.model.get('monitored')) { | ||||
|             this.ui.monitored.addClass('icon-bookmark'); | ||||
|             this.ui.monitored.removeClass('icon-bookmark-empty'); | ||||
|         } | ||||
|         else { | ||||
|             this.ui.monitored.addClass('icon-bookmark-empty'); | ||||
|             this.ui.monitored.removeClass('icon-bookmark'); | ||||
|         } | ||||
|     } | ||||
| }); | ||||
| @@ -1,10 +1,3 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette' | ||||
|     ], function (Marionette) { | ||||
| var Marionette = require('marionette'); | ||||
|  | ||||
|         return Marionette.ItemView.extend({ | ||||
|             template: 'Episode/Search/ButtonsViewTemplate' | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.ItemView.extend({template : 'Episode/Search/ButtonsViewTemplate'}); | ||||
| @@ -1,88 +1,63 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'vent', | ||||
|         'marionette', | ||||
|         'Episode/Search/ButtonsView', | ||||
|         'Episode/Search/ManualLayout', | ||||
|         'Release/ReleaseCollection', | ||||
|         'Series/SeriesCollection', | ||||
|         'Commands/CommandController', | ||||
|         'Shared/LoadingView', | ||||
|         'Episode/Search/NoResultsView' | ||||
|     ], function (vent, Marionette, ButtonsView, ManualSearchLayout, ReleaseCollection, SeriesCollection,CommandController, LoadingView, NoResultsView) { | ||||
| var vent = require('../../vent'); | ||||
| var Marionette = require('marionette'); | ||||
| var ButtonsView = require('./ButtonsView'); | ||||
| var ManualSearchLayout = require('./ManualLayout'); | ||||
| var ReleaseCollection = require('../../Release/ReleaseCollection'); | ||||
| var SeriesCollection = require('../../Series/SeriesCollection'); | ||||
| var CommandController = require('../../Commands/CommandController'); | ||||
| var LoadingView = require('../../Shared/LoadingView'); | ||||
| var NoResultsView = require('./NoResultsView'); | ||||
|  | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'Episode/Search/EpisodeSearchLayoutTemplate', | ||||
|  | ||||
|             regions: { | ||||
|                 main: '#episode-search-region' | ||||
|             }, | ||||
|  | ||||
|             events: { | ||||
|                 'click .x-search-auto'  : '_searchAuto', | ||||
|                 'click .x-search-manual': '_searchManual', | ||||
|                 'click .x-search-back'  : '_showButtons' | ||||
|             }, | ||||
|  | ||||
|             initialize: function () { | ||||
|                 this.mainView = new ButtonsView(); | ||||
|                 this.releaseCollection = new ReleaseCollection(); | ||||
|  | ||||
|                 this.listenTo(this.releaseCollection, 'sync', this._showSearchResults); | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 if (this.startManualSearch) { | ||||
|                     this._searchManual(); | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     this._showMainView(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             _searchAuto: function (e) { | ||||
|                 if (e) { | ||||
|                     e.preventDefault(); | ||||
|                 } | ||||
|  | ||||
|                 CommandController.Execute('episodeSearch', { | ||||
|                     episodeIds: [ this.model.get('id') ] | ||||
|                 }); | ||||
|  | ||||
|                 vent.trigger(vent.Commands.CloseModalCommand); | ||||
|             }, | ||||
|  | ||||
|             _searchManual: function (e) { | ||||
|                 if (e) { | ||||
|                     e.preventDefault(); | ||||
|                 } | ||||
|  | ||||
|                 this.mainView = new LoadingView(); | ||||
|                 this._showMainView(); | ||||
|                 this.releaseCollection.fetchEpisodeReleases(this.model.id); | ||||
|             }, | ||||
|  | ||||
|             _showMainView: function () { | ||||
|                 this.main.show(this.mainView); | ||||
|             }, | ||||
|  | ||||
|             _showButtons: function () { | ||||
|                 this.mainView = new ButtonsView(); | ||||
|                 this._showMainView(); | ||||
|             }, | ||||
|  | ||||
|             _showSearchResults: function () { | ||||
|                 if (this.releaseCollection.length === 0) { | ||||
|                     this.mainView = new NoResultsView(); | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     this.mainView = new ManualSearchLayout({ collection: this.releaseCollection }); | ||||
|                 } | ||||
|  | ||||
|                 this._showMainView(); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template           : 'Episode/Search/EpisodeSearchLayoutTemplate', | ||||
|     regions            : {main : '#episode-search-region'}, | ||||
|     events             : { | ||||
|         "click .x-search-auto"   : '_searchAuto', | ||||
|         "click .x-search-manual" : '_searchManual', | ||||
|         "click .x-search-back"   : '_showButtons' | ||||
|     }, | ||||
|     initialize         : function(){ | ||||
|         this.mainView = new ButtonsView(); | ||||
|         this.releaseCollection = new ReleaseCollection(); | ||||
|         this.listenTo(this.releaseCollection, 'sync', this._showSearchResults); | ||||
|     }, | ||||
|     onShow             : function(){ | ||||
|         if(this.startManualSearch) { | ||||
|             this._searchManual(); | ||||
|         } | ||||
|         else { | ||||
|             this._showMainView(); | ||||
|         } | ||||
|     }, | ||||
|     _searchAuto        : function(e){ | ||||
|         if(e) { | ||||
|             e.preventDefault(); | ||||
|         } | ||||
|         CommandController.Execute('episodeSearch', {episodeIds : [this.model.get('id')]}); | ||||
|         vent.trigger(vent.Commands.CloseModalCommand); | ||||
|     }, | ||||
|     _searchManual      : function(e){ | ||||
|         if(e) { | ||||
|             e.preventDefault(); | ||||
|         } | ||||
|         this.mainView = new LoadingView(); | ||||
|         this._showMainView(); | ||||
|         this.releaseCollection.fetchEpisodeReleases(this.model.id); | ||||
|     }, | ||||
|     _showMainView      : function(){ | ||||
|         this.main.show(this.mainView); | ||||
|     }, | ||||
|     _showButtons       : function(){ | ||||
|         this.mainView = new ButtonsView(); | ||||
|         this._showMainView(); | ||||
|     }, | ||||
|     _showSearchResults : function(){ | ||||
|         if(this.releaseCollection.length === 0) { | ||||
|             this.mainView = new NoResultsView(); | ||||
|         } | ||||
|         else { | ||||
|             this.mainView = new ManualSearchLayout({collection : this.releaseCollection}); | ||||
|         } | ||||
|         this._showMainView(); | ||||
|     } | ||||
| }); | ||||
| @@ -1,86 +1,64 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette', | ||||
|         'backgrid', | ||||
|         'Cells/ReleaseTitleCell', | ||||
|         'Cells/FileSizeCell', | ||||
|         'Cells/QualityCell', | ||||
|         'Cells/ApprovalStatusCell', | ||||
|         'Release/DownloadReportCell', | ||||
|         'Release/AgeCell', | ||||
|         'Release/ProtocolCell', | ||||
|         'Release/PeersCell' | ||||
|     ], function (Marionette, Backgrid, ReleaseTitleCell, FileSizeCell, QualityCell, ApprovalStatusCell, DownloadReportCell, AgeCell, ProtocolCell, PeersCell) { | ||||
| var Marionette = require('marionette'); | ||||
| var Backgrid = require('backgrid'); | ||||
| var ReleaseTitleCell = require('../../Cells/ReleaseTitleCell'); | ||||
| var FileSizeCell = require('../../Cells/FileSizeCell'); | ||||
| var QualityCell = require('../../Cells/QualityCell'); | ||||
| var ApprovalStatusCell = require('../../Cells/ApprovalStatusCell'); | ||||
| var DownloadReportCell = require('../../Release/DownloadReportCell'); | ||||
| var AgeCell = require('../../Release/AgeCell'); | ||||
| var ProtocolCell = require('../../Release/ProtocolCell'); | ||||
| var PeersCell = require('../../Release/PeersCell'); | ||||
|  | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'Episode/Search/ManualLayoutTemplate', | ||||
|  | ||||
|             regions: { | ||||
|                 grid: '#episode-release-grid' | ||||
|             }, | ||||
|  | ||||
|             columns: | ||||
|                 [ | ||||
|                     { | ||||
|                         name     : 'protocol', | ||||
|                         label    : 'Source', | ||||
|                         cell     : ProtocolCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name     : 'age', | ||||
|                         label    : 'Age', | ||||
|                         cell     : AgeCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name     : 'title', | ||||
|                         label    : 'Title', | ||||
|                         cell     : ReleaseTitleCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name     : 'indexer', | ||||
|                         label    : 'Indexer', | ||||
|                         cell     : Backgrid.StringCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name     : 'size', | ||||
|                         label    : 'Size', | ||||
|                         cell     : FileSizeCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name     : 'seeders', | ||||
|                         label    : 'Peers', | ||||
|                         cell     : PeersCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name     : 'quality', | ||||
|                         label    : 'Quality', | ||||
|                         cell     : QualityCell | ||||
|                     }, | ||||
|                     { | ||||
|                         name     : 'rejections', | ||||
|                         label    : '', | ||||
|                         cell     : ApprovalStatusCell, | ||||
|                         sortable : false | ||||
|                     }, | ||||
|                     { | ||||
|                         name     : 'download', | ||||
|                         label    : '', | ||||
|                         cell     : DownloadReportCell, | ||||
|                         sortable : true // Is the default sort, which sorts by the internal prioritization logic. | ||||
|                     } | ||||
|                 ], | ||||
|  | ||||
|             onShow: function () { | ||||
|                 if (!this.isClosed) { | ||||
|                     this.grid.show(new Backgrid.Grid({ | ||||
|                         row       : Backgrid.Row, | ||||
|                         columns   : this.columns, | ||||
|                         collection: this.collection, | ||||
|                         className : 'table table-hover' | ||||
|                     })); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|     }); | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template : 'Episode/Search/ManualLayoutTemplate', | ||||
|     regions  : {grid : '#episode-release-grid'}, | ||||
|     columns  : [{ | ||||
|         name  : 'protocol', | ||||
|         label : 'Source', | ||||
|         cell  : ProtocolCell | ||||
|     }, { | ||||
|         name  : 'age', | ||||
|         label : 'Age', | ||||
|         cell  : AgeCell | ||||
|     }, { | ||||
|         name  : 'title', | ||||
|         label : 'Title', | ||||
|         cell  : ReleaseTitleCell | ||||
|     }, { | ||||
|         name  : 'indexer', | ||||
|         label : 'Indexer', | ||||
|         cell  : Backgrid.StringCell | ||||
|     }, { | ||||
|         name  : 'size', | ||||
|         label : 'Size', | ||||
|         cell  : FileSizeCell | ||||
|     }, { | ||||
|         name  : 'seeders', | ||||
|         label : 'Peers', | ||||
|         cell  : PeersCell | ||||
|     }, { | ||||
|         name  : 'quality', | ||||
|         label : 'Quality', | ||||
|         cell  : QualityCell | ||||
|     }, { | ||||
|         name     : 'rejections', | ||||
|         label    : '', | ||||
|         cell     : ApprovalStatusCell, | ||||
|         sortable : false | ||||
|     }, { | ||||
|         name     : 'download', | ||||
|         label    : '', | ||||
|         cell     : DownloadReportCell, | ||||
|         sortable : true | ||||
|     }], | ||||
|     onShow   : function(){ | ||||
|         if(!this.isClosed) { | ||||
|             this.grid.show(new Backgrid.Grid({ | ||||
|                 row        : Backgrid.Row, | ||||
|                 columns    : this.columns, | ||||
|                 collection : this.collection, | ||||
|                 className  : 'table table-hover' | ||||
|             })); | ||||
|         } | ||||
|     } | ||||
| }); | ||||
| @@ -1,10 +1,3 @@ | ||||
| 'use strict'; | ||||
| var Marionette = require('marionette'); | ||||
|  | ||||
| define( | ||||
|     [ | ||||
|         'marionette' | ||||
|     ], function (Marionette) { | ||||
|         return Marionette.ItemView.extend({ | ||||
|             template: 'Episode/Search/NoResultsViewTemplate' | ||||
|         }); | ||||
|     }); | ||||
| module.exports = Marionette.ItemView.extend({template : 'Episode/Search/NoResultsViewTemplate'}); | ||||
| @@ -1,134 +1,97 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'reqres', | ||||
|         'marionette', | ||||
|         'backgrid', | ||||
|         'Series/EpisodeFileModel', | ||||
|         'Series/EpisodeFileCollection', | ||||
|         'Cells/FileSizeCell', | ||||
|         'Cells/QualityCell', | ||||
|         'Cells/DeleteEpisodeFileCell', | ||||
|         'Episode/Summary/NoFileView', | ||||
|         'Shared/LoadingView' | ||||
|     ], function (reqres, | ||||
|                  Marionette, | ||||
|                  Backgrid, | ||||
|                  EpisodeFileModel, | ||||
|                  EpisodeFileCollection, | ||||
|                  FileSizeCell, | ||||
|                  QualityCell, | ||||
|                  DeleteEpisodeFileCell, | ||||
|                  NoFileView, | ||||
|                  LoadingView) { | ||||
| var reqres = require('../../reqres'); | ||||
| var Marionette = require('marionette'); | ||||
| var Backgrid = require('backgrid'); | ||||
| var EpisodeFileModel = require('../../Series/EpisodeFileModel'); | ||||
| var EpisodeFileCollection = require('../../Series/EpisodeFileCollection'); | ||||
| var FileSizeCell = require('../../Cells/FileSizeCell'); | ||||
| var QualityCell = require('../../Cells/QualityCell'); | ||||
| var DeleteEpisodeFileCell = require('../../Cells/DeleteEpisodeFileCell'); | ||||
| var NoFileView = require('./NoFileView'); | ||||
| var LoadingView = require('../../Shared/LoadingView'); | ||||
|  | ||||
|         return Marionette.Layout.extend({ | ||||
|             template: 'Episode/Summary/EpisodeSummaryLayoutTemplate', | ||||
|  | ||||
|             regions: { | ||||
|                 overview: '.episode-overview', | ||||
|                 activity: '.episode-file-info' | ||||
|             }, | ||||
|  | ||||
|             columns: | ||||
|                 [ | ||||
|                     { | ||||
|                         name    : 'path', | ||||
|                         label   : 'Path', | ||||
|                         cell    : 'string', | ||||
|                         sortable: false | ||||
|                     }, | ||||
|                     { | ||||
|                         name    : 'size', | ||||
|                         label   : 'Size', | ||||
|                         cell    : FileSizeCell, | ||||
|                         sortable: false | ||||
|                     }, | ||||
|                     { | ||||
|                         name    : 'quality', | ||||
|                         label   : 'Quality', | ||||
|                         cell    : QualityCell, | ||||
|                         sortable: false, | ||||
|                         editable: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name    : 'this', | ||||
|                         label   : '', | ||||
|                         cell    : DeleteEpisodeFileCell, | ||||
|                         sortable: false | ||||
|                     } | ||||
|                 ], | ||||
|  | ||||
|             templateHelpers: {}, | ||||
|  | ||||
|             initialize: function (options) { | ||||
|                 if (!this.model.series) { | ||||
|                     this.templateHelpers.series = options.series.toJSON(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             onShow: function () { | ||||
|                 if (this.model.get('hasFile')) { | ||||
|                     var episodeFileId = this.model.get('episodeFileId'); | ||||
|  | ||||
|                     if (reqres.hasHandler(reqres.Requests.GetEpisodeFileById)) { | ||||
|                         var episodeFile = reqres.request(reqres.Requests.GetEpisodeFileById, episodeFileId); | ||||
|                         this.episodeFileCollection = new EpisodeFileCollection(episodeFile, { seriesId: this.model.get('seriesId') }); | ||||
|                         this.listenTo(episodeFile, 'destroy', this._episodeFileDeleted); | ||||
|  | ||||
|                         this._showTable(); | ||||
|                     } | ||||
|  | ||||
|                     else { | ||||
|                         this.activity.show(new LoadingView()); | ||||
|  | ||||
|                         var self = this; | ||||
|                         var newEpisodeFile = new EpisodeFileModel({ id: episodeFileId }); | ||||
|                         this.episodeFileCollection = new EpisodeFileCollection(newEpisodeFile, { seriesId: this.model.get('seriesId') }); | ||||
|                         var promise = newEpisodeFile.fetch(); | ||||
|                         this.listenTo(newEpisodeFile, 'destroy', this._episodeFileDeleted); | ||||
|  | ||||
|                         promise.done(function () { | ||||
|                            self._showTable(); | ||||
|                         }); | ||||
|                     } | ||||
|  | ||||
|                     this.listenTo(this.episodeFileCollection, 'add remove', this._collectionChanged); | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     this._showNoFileView(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             _showTable: function () { | ||||
|                 this.activity.show(new Backgrid.Grid({ | ||||
|                     collection: this.episodeFileCollection, | ||||
|                     columns   : this.columns, | ||||
|                     className : 'table table-bordered', | ||||
|                     emptyText : 'Nothing to see here!' | ||||
|                 })); | ||||
|             }, | ||||
|  | ||||
|             _showNoFileView: function () { | ||||
|                 this.activity.show(new NoFileView()); | ||||
|             }, | ||||
|  | ||||
|             _collectionChanged: function () { | ||||
|                 if (!this.episodeFileCollection.any()) { | ||||
|                     this._showNoFileView(); | ||||
|                 } | ||||
|  | ||||
|                 else { | ||||
|                     this._showTable(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             _episodeFileDeleted: function () { | ||||
|                 this.model.set({ | ||||
|                     episodeFileId: 0, | ||||
|                     hasFile      : false | ||||
| module.exports = Marionette.Layout.extend({ | ||||
|     template            : 'Episode/Summary/EpisodeSummaryLayoutTemplate', | ||||
|     regions             : { | ||||
|         overview : '.episode-overview', | ||||
|         activity : '.episode-file-info' | ||||
|     }, | ||||
|     columns             : [{ | ||||
|         name     : 'path', | ||||
|         label    : 'Path', | ||||
|         cell     : 'string', | ||||
|         sortable : false | ||||
|     }, { | ||||
|         name     : 'size', | ||||
|         label    : 'Size', | ||||
|         cell     : FileSizeCell, | ||||
|         sortable : false | ||||
|     }, { | ||||
|         name     : 'quality', | ||||
|         label    : 'Quality', | ||||
|         cell     : QualityCell, | ||||
|         sortable : false, | ||||
|         editable : true | ||||
|     }, { | ||||
|         name     : 'this', | ||||
|         label    : '', | ||||
|         cell     : DeleteEpisodeFileCell, | ||||
|         sortable : false | ||||
|     }], | ||||
|     templateHelpers     : {}, | ||||
|     initialize          : function(options){ | ||||
|         if(!this.model.series) { | ||||
|             this.templateHelpers.series = options.series.toJSON(); | ||||
|         } | ||||
|     }, | ||||
|     onShow              : function(){ | ||||
|         if(this.model.get('hasFile')) { | ||||
|             var episodeFileId = this.model.get('episodeFileId'); | ||||
|             if(reqres.hasHandler(reqres.Requests.GetEpisodeFileById)) { | ||||
|                 var episodeFile = reqres.request(reqres.Requests.GetEpisodeFileById, episodeFileId); | ||||
|                 this.episodeFileCollection = new EpisodeFileCollection(episodeFile, {seriesId : this.model.get('seriesId')}); | ||||
|                 this.listenTo(episodeFile, 'destroy', this._episodeFileDeleted); | ||||
|                 this._showTable(); | ||||
|             } | ||||
|             else { | ||||
|                 this.activity.show(new LoadingView()); | ||||
|                 var self = this; | ||||
|                 var newEpisodeFile = new EpisodeFileModel({id : episodeFileId}); | ||||
|                 this.episodeFileCollection = new EpisodeFileCollection(newEpisodeFile, {seriesId : this.model.get('seriesId')}); | ||||
|                 var promise = newEpisodeFile.fetch(); | ||||
|                 this.listenTo(newEpisodeFile, 'destroy', this._episodeFileDeleted); | ||||
|                 promise.done(function(){ | ||||
|                     self._showTable(); | ||||
|                 }); | ||||
|             } | ||||
|             this.listenTo(this.episodeFileCollection, 'add remove', this._collectionChanged); | ||||
|         } | ||||
|         else { | ||||
|             this._showNoFileView(); | ||||
|         } | ||||
|     }, | ||||
|     _showTable          : function(){ | ||||
|         this.activity.show(new Backgrid.Grid({ | ||||
|             collection : this.episodeFileCollection, | ||||
|             columns    : this.columns, | ||||
|             className  : 'table table-bordered', | ||||
|             emptyText  : 'Nothing to see here!' | ||||
|         })); | ||||
|     }, | ||||
|     _showNoFileView     : function(){ | ||||
|         this.activity.show(new NoFileView()); | ||||
|     }, | ||||
|     _collectionChanged  : function(){ | ||||
|         if(!this.episodeFileCollection.any()) { | ||||
|             this._showNoFileView(); | ||||
|         } | ||||
|         else { | ||||
|             this._showTable(); | ||||
|         } | ||||
|     }, | ||||
|     _episodeFileDeleted : function(){ | ||||
|         this.model.set({ | ||||
|             episodeFileId : 0, | ||||
|             hasFile       : false | ||||
|         }); | ||||
|     }); | ||||
|     } | ||||
| }); | ||||
| @@ -1,11 +1,3 @@ | ||||
| 'use strict'; | ||||
| define( | ||||
|     [ | ||||
|         'marionette' | ||||
|     ], function (Marionette) { | ||||
| var Marionette = require('marionette'); | ||||
|  | ||||
|         return Marionette.ItemView.extend({ | ||||
|             template: 'Episode/Summary/NoFileViewTemplate' | ||||
|         }); | ||||
|  | ||||
|     }); | ||||
| module.exports = Marionette.ItemView.extend({template : 'Episode/Summary/NoFileViewTemplate'}); | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user