rjs -> webpack

This commit is contained in:
Keivan Beigi 2015-02-02 17:18:45 -08:00
parent 344f3d66ef
commit 428a1439e5
399 changed files with 11591 additions and 16139 deletions

1
.gitignore vendored
View File

@ -122,3 +122,4 @@ setup/Output/
#VS outout folders #VS outout folders
bin bin
obj obj
output/*

View File

@ -221,15 +221,12 @@ Function PackageTests()
Function RunGulp() Function RunGulp()
{ {
Write-Host "##teamcity[progressStart 'Running Gulp']" Write-Host "##teamcity[progressStart 'Running Gulp']"
$gulpPath = '.\node_modules\gulp\bin\gulp'
Invoke-Expression 'npm install' Invoke-Expression 'npm install'
CheckExitCode CheckExitCode
Invoke-Expression ('node ' + $gulpPath + ' build') -ErrorAction Continue -Verbose Invoke-Expression 'gulp build' -ErrorAction Continue -Verbose
CheckExitCode CheckExitCode
Remove-Item $outputFolder\UI\build.txt -ErrorAction Continue
Write-Host "##teamcity[progressFinish 'Running Gulp']" Write-Host "##teamcity[progressFinish 'Running Gulp']"
} }

50
commonjsCleanup.linq Normal file
View 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

View File

@ -2,12 +2,11 @@ var gulp = require('gulp');
var runSequence = require('run-sequence'); var runSequence = require('run-sequence');
require('./clean'); require('./clean');
require('./requirejs');
require('./less'); require('./less');
require('./handlebars'); require('./handlebars');
require('./copy'); require('./copy');
gulp.task('build', function () { gulp.task('build', function () {
return runSequence('clean', return runSequence('clean',
['requireJs', 'less', 'handlebars', 'copyHtml', 'copyContent']); ['webpack', 'less', 'handlebars', 'copyHtml', 'copyContent', 'copyJs']);
}); });

View File

@ -5,7 +5,12 @@ var cache = require('gulp-cached');
var paths = require('./paths.js'); var paths = require('./paths.js');
gulp.task('copyJs', function () { 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(cache('copyJs'))
.pipe(print()) .pipe(print())
.pipe(gulp.dest(paths.dest.root)); .pipe(gulp.dest(paths.dest.root));

View File

@ -1,12 +1,12 @@
require('./watch.js'); require('./watch.js');
require('./build.js'); require('./build.js');
require('./clean.js'); require('./clean.js');
require('./requirejs.js');
require('./jshint.js'); require('./jshint.js');
require('./handlebars.js'); require('./handlebars.js');
require('./copy.js'); require('./copy.js');
require('./less.js'); require('./less.js');
require('./stripBom.js'); require('./stripBom.js');
require('./imageMin.js'); require('./imageMin.js');
require('./webpack.js');

View File

@ -2,7 +2,6 @@ var gulp = require('gulp');
var handlebars = require('gulp-handlebars'); var handlebars = require('gulp-handlebars');
var declare = require('gulp-declare'); var declare = require('gulp-declare');
var concat = require('gulp-concat'); var concat = require('gulp-concat');
var wrapAmd = require('gulp-wrap-amd');
var wrap = require("gulp-wrap"); var wrap = require("gulp-wrap");
var path = require('path'); var path = require('path');
var streamqueue = require('streamqueue'); var streamqueue = require('streamqueue');
@ -48,10 +47,6 @@ gulp.task('handlebars', function () {
partialStream, partialStream,
coreStream coreStream
).pipe(concat('templates.js')) ).pipe(concat('templates.js'))
.pipe(wrapAmd({
deps: ['handlebars'],
params: ['Handlebars'],
exports: 'this["T"]'
}))
.pipe(gulp.dest(paths.dest.root)); .pipe(gulp.dest(paths.dest.root));
}); });

View File

@ -15,6 +15,7 @@ gulp.task('jshint', function () {
'-W100': false, //Silently deleted characters (in locales) '-W100': false, //Silently deleted characters (in locales)
'undef': true, 'undef': true,
'globals': { 'globals': {
'module': true,
'require': true, 'require': true,
'define': true, 'define': true,
'window': true, 'window': true,

View File

@ -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();
});
});

View File

@ -8,17 +8,19 @@ require('./jshint.js');
require('./handlebars.js'); require('./handlebars.js');
require('./less.js'); require('./less.js');
require('./copy.js'); require('./copy.js');
require('./webpack.js');
gulp.task('watch', ['jshint', 'handlebars', 'less', 'copyJs', 'copyHtml', 'copyContent'], function () { gulp.task('watch', ['jshint', 'handlebars', 'less','copyHtml', 'copyContent','copyJs'], function () {
gulp.watch([paths.src.scripts, paths.src.exclude.libs], ['jshint', 'copyJs']); gulp.start('webpackWatch');
gulp.watch([paths.src.scripts, paths.src.exclude.libs], ['jshint','copyJs']);
gulp.watch(paths.src.templates, ['handlebars']); gulp.watch(paths.src.templates, ['handlebars']);
gulp.watch([paths.src.less, paths.src.exclude.libs], ['less']); gulp.watch([paths.src.less, paths.src.exclude.libs], ['less']);
gulp.watch([paths.src.html], ['copyHtml']); gulp.watch([paths.src.html], ['copyHtml']);
gulp.watch([paths.src.content + '**/*.*', '!**/*.less'], ['copyContent']); 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(); var server = livereload();
gulp.watch([ gulp.watch([
'app/**/*.js', 'app/**/*.js',

20
gulp/webpack.js Normal file
View 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(''));
});

View File

@ -1,8 +1,8 @@
{ {
"name": "Sonarr", "name": "Sonarr",
"version": "0.0.0", "version": "2.0.0",
"description": "Sonarr", "description": "Sonarr",
"main": "index.js", "main": "main.js",
"scripts": { "scripts": {
"preinstall": "" "preinstall": ""
}, },
@ -15,10 +15,10 @@
"gitHead": "9ff7aa1bf7fe38c4c5bdb92f56c8ad556916ed67", "gitHead": "9ff7aa1bf7fe38c4c5bdb92f56c8ad556916ed67",
"readmeFilename": "readme.md", "readmeFilename": "readme.md",
"dependencies": { "dependencies": {
"del": "0.1.3",
"fs-extra": "0.12.0", "fs-extra": "0.12.0",
"gulp": "3.8.10", "gulp": "3.8.10",
"gulp-cached": "1.0.1", "gulp-cached": "1.0.1",
"del": "0.1.3",
"gulp-concat": "2.4.2", "gulp-concat": "2.4.2",
"gulp-declare": "0.3.0", "gulp-declare": "0.3.0",
"gulp-handlebars": "2.2.0", "gulp-handlebars": "2.2.0",
@ -26,10 +26,11 @@
"gulp-less": "1.3.6", "gulp-less": "1.3.6",
"gulp-print": "1.1.0", "gulp-print": "1.1.0",
"gulp-replace": "0.5.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": "0.5.0",
"gulp-wrap-amd": "0.3.1",
"jshint-stylish": "1.0.0", "jshint-stylish": "1.0.0",
"requirejs": "2.1.15",
"run-sequence": "1.0.2", "run-sequence": "1.0.2",
"streamqueue": "0.1.1" "streamqueue": "0.1.1"
} }

View File

@ -27,6 +27,7 @@ namespace NzbDrone.Api.Frontend.Mappers
{ {
return resourceUrl.StartsWith("/Content") || return resourceUrl.StartsWith("/Content") ||
resourceUrl.EndsWith(".js") || resourceUrl.EndsWith(".js") ||
resourceUrl.EndsWith(".map") ||
resourceUrl.EndsWith(".css") || resourceUrl.EndsWith(".css") ||
(resourceUrl.EndsWith(".ico") && !resourceUrl.Equals("/favicon.ico")) || (resourceUrl.EndsWith(".ico") && !resourceUrl.Equals("/favicon.ico")) ||
resourceUrl.EndsWith(".swf"); resourceUrl.EndsWith(".swf");

View File

@ -19,6 +19,8 @@
<JSCodeStyleSettings> <JSCodeStyleSettings>
<option name="SPACE_BEFORE_PROPERTY_COLON" value="true" /> <option name="SPACE_BEFORE_PROPERTY_COLON" value="true" />
<option name="ALIGN_OBJECT_PROPERTIES" value="2" /> <option name="ALIGN_OBJECT_PROPERTIES" value="2" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="OBJECT_LITERAL_WRAP" value="2" />
</JSCodeStyleSettings> </JSCodeStyleSettings>
<XML> <XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" /> <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
@ -29,14 +31,18 @@
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="JavaScript"> <codeStyleSettings language="JavaScript">
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="true" />
<option name="KEEP_LINE_BREAKS" value="false" /> <option name="KEEP_LINE_BREAKS" value="false" />
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" /> <option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="ELSE_ON_NEW_LINE" value="true" /> <option name="ELSE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" /> <option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_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="SPACE_BEFORE_METHOD_PARENTHESES" value="true" />
<option name="METHOD_PARAMETERS_WRAP" value="5" /> <option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
<option name="ARRAY_INITIALIZER_WRAP" value="2" /> <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="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" /> <option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" /> <option name="WHILE_BRACE_FORCE" value="3" />
@ -46,5 +52,4 @@
</option> </option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" /> <option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component> </component>
</project> </project>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" /> <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false">
</project> <file url="file://$PROJECT_DIR$/System/Logs/Files/LogFileModel.js" charset="UTF-8" />
</component>
</project>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <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 bitwise="true" />
<option camelcase="true" /> <option camelcase="true" />
<option curly="true" /> <option curly="true" />
@ -14,7 +14,7 @@
<option nonew="true" /> <option nonew="true" />
<option plusplus="false" /> <option plusplus="false" />
<option undef="true" /> <option undef="true" />
<option strict="true" /> <option strict="false" />
<option trailing="false" /> <option trailing="false" />
<option latedef="true" /> <option latedef="true" />
<option unused="true" /> <option unused="true" />
@ -27,40 +27,46 @@
<option esnext="false" /> <option esnext="false" />
<option evil="false" /> <option evil="false" />
<option expr="false" /> <option expr="false" />
<option funcscope="false" />
<option globalstrict="true" /> <option globalstrict="true" />
<option iterator="false" />
<option lastsemic="false" /> <option lastsemic="false" />
<option laxbreak="false" /> <option laxbreak="false" />
<option laxcomma="false" /> <option laxcomma="false" />
<option loopfunc="false" />
<option multistr="false" /> <option multistr="false" />
<option notypeof="false" />
<option proto="false" /> <option proto="false" />
<option scripturl="false" /> <option scripturl="false" />
<option smarttabs="false" />
<option shadow="false" />
<option sub="false" /> <option sub="false" />
<option supernew="false" />
<option validthis="false" />
<option browser="true" /> <option browser="true" />
<option couch="false" /> <option couch="false" />
<option devel="true" /> <option devel="true" />
<option dojo="false" /> <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 jquery="false" />
<option mootools="false" />
<option node="false" />
<option nonstandard="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 prototypejs="false" />
<option rhino="false" /> <option rhino="false" />
<option worker="false" /> <option worker="false" />
<option wsh="false" /> <option wsh="false" />
<option yui="false" /> <option yui="false" />
<option nomen="false" />
<option onevar="false" /> <option onevar="false" />
<option passfail="false" /> <option passfail="false" />
<option white="false" /> <option white="false" />
<option maxerr="50" /> <option predef="window, define, require, module" />
<option predef="window, define, require" />
</component> </component>
</project> </project>

View File

@ -1,85 +1,72 @@
'use strict'; var Marionette = require('marionette');
define( var Backbone = require('backbone');
[ var Backgrid = require('backgrid');
'marionette', var HistoryLayout = require('./History/HistoryLayout');
'backbone', var BlacklistLayout = require('./Blacklist/BlacklistLayout');
'backgrid', var QueueLayout = require('./Queue/QueueLayout');
'Activity/History/HistoryLayout',
'Activity/Blacklist/BlacklistLayout',
'Activity/Queue/QueueLayout'
], function (Marionette, Backbone, Backgrid, HistoryLayout, BlacklistLayout, QueueLayout) {
return Marionette.Layout.extend({
template: 'Activity/ActivityLayoutTemplate',
regions: { module.exports = Marionette.Layout.extend({
queueRegion : '#queue', template : 'Activity/ActivityLayoutTemplate',
history : '#history', regions : {
blacklist : '#blacklist' queueRegion : '#queue',
}, history : '#history',
blacklist : '#blacklist'
ui: { },
queueTab : '.x-queue-tab', ui : {
historyTab : '.x-history-tab', queueTab : '.x-queue-tab',
blacklistTab : '.x-blacklist-tab' historyTab : '.x-history-tab',
}, blacklistTab : '.x-blacklist-tab'
},
events: { events : {
'click .x-queue-tab' : '_showQueue', "click .x-queue-tab" : '_showQueue',
'click .x-history-tab' : '_showHistory', "click .x-history-tab" : '_showHistory',
'click .x-blacklist-tab' : '_showBlacklist' "click .x-blacklist-tab" : '_showBlacklist'
}, },
initialize : function(options){
initialize: function (options) { if(options.action) {
if (options.action) { this.action = options.action.toLowerCase();
this.action = options.action.toLowerCase(); }
} },
}, onShow : function(){
switch (this.action) {
onShow: function () { case 'history':
switch (this.action) { this._showHistory();
case 'history': break;
this._showHistory(); case 'blacklist':
break; this._showBlacklist();
case 'blacklist': break;
this._showBlacklist(); default:
break; this._showQueue();
default: }
this._showQueue(); },
} _navigate : function(route){
}, Backbone.history.navigate(route, {
trigger : false,
_navigate: function (route) { replace : true
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');
}
}); });
}); },
_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');
}
});

View File

@ -1,26 +1,16 @@
'use strict'; var NzbDroneCell = require('../../Cells/NzbDroneCell');
define( module.exports = NzbDroneCell.extend({
[ className : 'blacklist-controls-cell',
'Cells/NzbDroneCell' events : {
], function (NzbDroneCell) { 'click' : '_delete'
return NzbDroneCell.extend({ },
render : function(){
className: 'blacklist-controls-cell', this.$el.empty();
this.$el.html('<i class="icon-nd-delete"></i>');
events: { return this;
'click': '_delete' },
}, _delete : function(){
this.model.destroy();
render: function () { }
this.$el.empty(); });
this.$el.html('<i class="icon-nd-delete"></i>');
return this;
},
_delete: function () {
this.model.destroy();
}
});
});

View File

@ -1,50 +1,39 @@
'use strict'; var BlacklistModel = require('./BlacklistModel');
define( var PageableCollection = require('backbone.pageable');
[ var AsSortedCollection = require('../../Mixins/AsSortedCollection');
'Activity/Blacklist/BlacklistModel', var AsPersistedStateCollection = require('../../Mixins/AsPersistedStateCollection');
'backbone.pageable',
'Mixins/AsSortedCollection',
'Mixins/AsPersistedStateCollection'
], function (BlacklistModel, PageableCollection, AsSortedCollection, AsPersistedStateCollection) {
var Collection = PageableCollection.extend({
url : window.NzbDrone.ApiRoot + '/blacklist',
model: BlacklistModel,
state: { module.exports = (function(){
pageSize: 15, var Collection = PageableCollection.extend({
sortKey : 'date', url : window.NzbDrone.ApiRoot + '/blacklist',
order : 1 model : BlacklistModel,
}, state : {
pageSize : 15,
queryParams: { sortKey : 'date',
totalPages : null, order : 1
totalRecords: null, },
pageSize : 'pageSize', queryParams : {
sortKey : 'sortKey', totalPages : null,
order : 'sortDir', totalRecords : null,
directions : { pageSize : 'pageSize',
'-1': 'asc', sortKey : 'sortKey',
'1' : 'desc' 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;
} }
}); },
sortMappings : {'series' : {sortKey : 'series.sortTitle'}},
Collection = AsSortedCollection.call(Collection); parseState : function(resp){
return AsPersistedStateCollection.call(Collection); return {totalRecords : resp.totalRecords};
},
parseRecords : function(resp){
if(resp) {
return resp.records;
}
return resp;
}
}); });
Collection = AsSortedCollection.call(Collection);
return AsPersistedStateCollection.call(Collection);
}).call(this);

View File

@ -1,131 +1,91 @@
'use strict'; var vent = require('../../vent');
define( var Marionette = require('marionette');
[ var Backgrid = require('backgrid');
'vent', var BlacklistCollection = require('./BlacklistCollection');
'marionette', var SeriesTitleCell = require('../../Cells/SeriesTitleCell');
'backgrid', var QualityCell = require('../../Cells/QualityCell');
'Activity/Blacklist/BlacklistCollection', var RelativeDateCell = require('../../Cells/RelativeDateCell');
'Cells/SeriesTitleCell', var BlacklistActionsCell = require('./BlacklistActionsCell');
'Cells/QualityCell', var GridPager = require('../../Shared/Grid/Pager');
'Cells/RelativeDateCell', var LoadingView = require('../../Shared/LoadingView');
'Activity/Blacklist/BlacklistActionsCell', var ToolbarLayout = require('../../Shared/Toolbar/ToolbarLayout');
'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',
regions: { module.exports = Marionette.Layout.extend({
blacklist : '#x-blacklist', template : 'Activity/Blacklist/BlacklistLayoutTemplate',
toolbar : '#x-toolbar', regions : {
pager : '#x-pager' blacklist : '#x-blacklist',
}, toolbar : '#x-toolbar',
pager : '#x-pager'
columns: },
[ columns : [{
{ name : 'series',
name : 'series', label : 'Series',
label : 'Series', cell : SeriesTitleCell
cell : SeriesTitleCell }, {
}, name : 'sourceTitle',
{ label : 'Source Title',
name : 'sourceTitle', cell : 'string'
label : 'Source Title', }, {
cell : 'string' name : 'quality',
}, label : 'Quality',
{ cell : QualityCell,
name : 'quality', sortable : false
label : 'Quality', }, {
cell : QualityCell, name : 'date',
sortable : false label : 'Date',
}, cell : RelativeDateCell
{ }, {
name : 'date', name : 'this',
label : 'Date', label : '',
cell : RelativeDateCell cell : BlacklistActionsCell,
}, sortable : false
{ }],
name : 'this', initialize : function(){
label : '', this.collection = new BlacklistCollection({tableName : 'blacklist'});
cell : BlacklistActionsCell, this.listenTo(this.collection, 'sync', this._showTable);
sortable : false this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete);
} },
], onShow : function(){
this.blacklist.show(new LoadingView());
initialize: function () { this._showToolbar();
this.collection = new BlacklistCollection({ tableName: 'blacklist' }); this.collection.fetch();
},
this.listenTo(this.collection, 'sync', this._showTable); _showTable : function(collection){
this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete); this.blacklist.show(new Backgrid.Grid({
}, columns : this.columns,
collection : collection,
onShow: function () { className : 'table table-hover'
this.blacklist.show(new LoadingView()); }));
this._showToolbar(); this.pager.show(new GridPager({
this.collection.fetch(); columns : this.columns,
}, collection : collection
}));
_showTable: function (collection) { },
_showToolbar : function(){
this.blacklist.show(new Backgrid.Grid({ var leftSideButtons = {
columns : this.columns, type : 'default',
collection: collection, storeState : false,
className : 'table table-hover' items : [{
})); title : 'Clear Blacklist',
icon : 'icon-trash',
this.pager.show(new GridPager({ command : 'clearBlacklist'
columns : this.columns, }]
collection: collection };
})); this.toolbar.show(new ToolbarLayout({
}, left : [leftSideButtons],
context : this
_showToolbar: function () { }));
var leftSideButtons = { },
type : 'default', _refreshTable : function(buttonContext){
storeState: false, this.collection.state.currentPage = 1;
items : var promise = this.collection.fetch({reset : true});
[ if(buttonContext) {
{ buttonContext.ui.icon.spinForPromise(promise);
title : 'Clear Blacklist', }
icon : 'icon-trash', },
command : 'clearBlacklist' _commandComplete : function(options){
} if(options.command.get('name') === 'clearblacklist') {
] this._refreshTable();
}; }
}
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();
}
}
});
});

View File

@ -1,21 +1,14 @@
'use strict'; var Backbone = require('backbone');
define( var SeriesCollection = require('../../Series/SeriesCollection');
[
'backbone',
'Series/SeriesCollection'
], function (Backbone, SeriesCollection) {
return Backbone.Model.extend({
//Hack to deal with Backbone 1.0's bug module.exports = Backbone.Model.extend({
initialize: function () { initialize : function(){
this.url = function () { this.url = function(){
return this.collection.url + '/' + this.get('id'); return this.collection.url + '/' + this.get('id');
}; };
}, },
parse : function(model){
parse: function (model) { model.series = SeriesCollection.get(model.seriesId);
model.series = SeriesCollection.get(model.seriesId); return model;
return model; }
} });
});
});

View File

@ -1,19 +1,13 @@
'use strict'; var Handlebars = require('handlebars');
define(
[
'handlebars'
], function (Handlebars) {
Handlebars.registerHelper('historyAge', function () { module.exports = (function(){
Handlebars.registerHelper('historyAge', function(){
var unit = 'days'; var unit = 'days';
var age = this.age; var age = this.age;
if(age < 2) {
if (age < 2) { unit = 'hours';
unit = 'hours'; age = parseFloat(this.ageHours).toFixed(1);
age = parseFloat(this.ageHours).toFixed(1); }
} return new Handlebars.SafeString('<dt>Age (when grabbed):</dt><dd>{0} {1}</dd>'.format(age, unit));
return new Handlebars.SafeString('<dt>Age (when grabbed):</dt><dd>{0} {1}</dd>'.format(age, unit));
});
}); });
}).call(this);

View File

@ -1,40 +1,23 @@
'use strict'; var $ = require('jquery');
define( var vent = require('../../../vent');
[ var Marionette = require('marionette');
'jquery', var HistoryDetailsView = require('./HistoryDetailsView');
'vent',
'marionette',
'Activity/History/Details/HistoryDetailsView'
], function ($, vent, Marionette, HistoryDetailsView) {
return Marionette.Layout.extend({ module.exports = Marionette.Layout.extend({
template: 'Activity/History/Details/HistoryDetailsLayoutTemplate', template : 'Activity/History/Details/HistoryDetailsLayoutTemplate',
regions : {bodyRegion : '.modal-body'},
regions: { events : {"click .x-mark-as-failed" : '_markAsFailed'},
bodyRegion: '.modal-body' onShow : function(){
}, this.bodyRegion.show(new HistoryDetailsView({model : this.model}));
},
events: { _markAsFailed : function(){
'click .x-mark-as-failed': '_markAsFailed' var url = window.NzbDrone.ApiRoot + '/history/failed';
}, var data = {id : this.model.get('id')};
$.ajax({
onShow: function () { url : url,
this.bodyRegion.show(new HistoryDetailsView({ model: this.model })); type : 'POST',
}, data : data
_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);
}
}); });
}); vent.trigger(vent.Commands.CloseModalCommand);
}
});

View File

@ -1,11 +1,4 @@
'use strict'; var Marionette = require('marionette');
define( require('./HistoryDetailsAge');
[
'marionette',
'Activity/History/Details/HistoryDetailsAge'
], function (Marionette) {
return Marionette.ItemView.extend({ module.exports = Marionette.ItemView.extend({template : 'Activity/History/Details/HistoryDetailsViewTemplate'});
template: 'Activity/History/Details/HistoryDetailsViewTemplate'
});
});

View File

@ -1,70 +1,56 @@
'use strict'; var HistoryModel = require('./HistoryModel');
define( var PageableCollection = require('backbone.pageable');
[ var AsFilteredCollection = require('../../Mixins/AsFilteredCollection');
'Activity/History/HistoryModel', var AsSortedCollection = require('../../Mixins/AsSortedCollection');
'backbone.pageable', var AsPersistedStateCollection = require('../../Mixins/AsPersistedStateCollection');
'Mixins/AsFilteredCollection',
'Mixins/AsSortedCollection',
'Mixins/AsPersistedStateCollection'
], function (HistoryModel, PageableCollection, AsFilteredCollection, AsSortedCollection, AsPersistedStateCollection) {
var Collection = PageableCollection.extend({
url : window.NzbDrone.ApiRoot + '/history',
model: HistoryModel,
state: { module.exports = (function(){
pageSize: 15, var Collection = PageableCollection.extend({
sortKey : 'date', url : window.NzbDrone.ApiRoot + '/history',
order : 1 model : HistoryModel,
}, state : {
pageSize : 15,
queryParams: { sortKey : 'date',
totalPages : null, order : 1
totalRecords: null, },
pageSize : 'pageSize', queryParams : {
sortKey : 'sortKey', totalPages : null,
order : 'sortDir', totalRecords : null,
directions : { pageSize : 'pageSize',
'-1': 'asc', sortKey : 'sortKey',
'1' : 'desc' 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;
} }
}); },
filterModes : {
Collection = AsFilteredCollection.call(Collection); "all" : [null, null],
Collection = AsSortedCollection.call(Collection); "grabbed" : ['eventType', '1'],
return AsPersistedStateCollection.call(Collection); "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);

View File

@ -1,27 +1,15 @@
'use strict'; var vent = require('../../vent');
var NzbDroneCell = require('../../Cells/NzbDroneCell');
define( module.exports = NzbDroneCell.extend({
[ className : 'history-details-cell',
'vent', events : {"click" : '_showDetails'},
'Cells/NzbDroneCell' render : function(){
], function (vent, NzbDroneCell) { this.$el.empty();
return NzbDroneCell.extend({ this.$el.html('<i class="icon-info-sign"></i>');
return this;
className: 'history-details-cell', },
_showDetails : function(){
events: { vent.trigger(vent.Commands.ShowHistoryDetails, {model : this.model});
'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 });
}
});
});

View File

@ -1,173 +1,126 @@
'use strict'; var Marionette = require('marionette');
define( var Backgrid = require('backgrid');
[ var HistoryCollection = require('./HistoryCollection');
'marionette', var EventTypeCell = require('../../Cells/EventTypeCell');
'backgrid', var SeriesTitleCell = require('../../Cells/SeriesTitleCell');
'Activity/History/HistoryCollection', var EpisodeNumberCell = require('../../Cells/EpisodeNumberCell');
'Cells/EventTypeCell', var EpisodeTitleCell = require('../../Cells/EpisodeTitleCell');
'Cells/SeriesTitleCell', var HistoryQualityCell = require('./HistoryQualityCell');
'Cells/EpisodeNumberCell', var RelativeDateCell = require('../../Cells/RelativeDateCell');
'Cells/EpisodeTitleCell', var HistoryDetailsCell = require('./HistoryDetailsCell');
'Activity/History/HistoryQualityCell', var GridPager = require('../../Shared/Grid/Pager');
'Cells/RelativeDateCell', var ToolbarLayout = require('../../Shared/Toolbar/ToolbarLayout');
'Activity/History/HistoryDetailsCell', var LoadingView = require('../../Shared/LoadingView');
'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',
regions: { module.exports = Marionette.Layout.extend({
history: '#x-history', template : 'Activity/History/HistoryLayoutTemplate',
toolbar: '#x-history-toolbar', regions : {
pager : '#x-history-pager' history : '#x-history',
}, toolbar : '#x-history-toolbar',
pager : '#x-history-pager'
columns: },
[ columns : [{
{ name : 'eventType',
name : 'eventType', label : '',
label : '', cell : EventTypeCell,
cell : EventTypeCell, cellValue : 'this'
cellValue : 'this' }, {
}, name : 'series',
{ label : 'Series',
name : 'series', cell : SeriesTitleCell
label : 'Series', }, {
cell : SeriesTitleCell name : 'episode',
}, label : 'Episode',
{ cell : EpisodeNumberCell,
name : 'episode', sortable : false
label : 'Episode', }, {
cell : EpisodeNumberCell, name : 'episode',
sortable : false label : 'Episode Title',
}, cell : EpisodeTitleCell,
{ sortable : false
name : 'episode', }, {
label : 'Episode Title', name : 'this',
cell : EpisodeTitleCell, label : 'Quality',
sortable : false cell : HistoryQualityCell,
}, sortable : false
{ }, {
name : 'this', name : 'date',
label : 'Quality', label : 'Date',
cell : HistoryQualityCell, cell : RelativeDateCell
sortable : false }, {
}, name : 'this',
{ label : '',
name : 'date', cell : HistoryDetailsCell,
label : 'Date', sortable : false
cell : RelativeDateCell }],
}, initialize : function(){
{ this.collection = new HistoryCollection({tableName : 'history'});
name : 'this', this.listenTo(this.collection, 'sync', this._showTable);
label : '', },
cell : HistoryDetailsCell, onShow : function(){
sortable : false this.history.show(new LoadingView());
} this._showToolbar();
], },
_showTable : function(collection){
initialize: function () { this.history.show(new Backgrid.Grid({
this.collection = new HistoryCollection({ tableName: 'history' }); columns : this.columns,
this.listenTo(this.collection, 'sync', this._showTable); collection : collection,
}, className : 'table table-hover'
}));
onShow: function () { this.pager.show(new GridPager({
this.history.show(new LoadingView()); columns : this.columns,
this._showToolbar(); collection : collection
}, }));
},
_showTable: function (collection) { _showToolbar : function(){
var filterOptions = {
this.history.show(new Backgrid.Grid({ type : 'radio',
columns : this.columns, storeState : true,
collection: collection, menuKey : 'history.filterMode',
className : 'table table-hover' defaultAction : 'all',
})); items : [{
key : 'all',
this.pager.show(new GridPager({ title : '',
columns : this.columns, tooltip : 'All',
collection: collection icon : 'icon-circle-blank',
})); callback : this._setFilter
}, }, {
key : 'grabbed',
_showToolbar: function () { title : '',
var filterOptions = { tooltip : 'Grabbed',
type : 'radio', icon : 'icon-nd-downloading',
storeState : true, callback : this._setFilter
menuKey : 'history.filterMode', }, {
defaultAction : 'all', key : 'imported',
items : title : '',
[ tooltip : 'Imported',
{ icon : 'icon-nd-imported',
key : 'all', callback : this._setFilter
title : '', }, {
tooltip : 'All', key : 'failed',
icon : 'icon-circle-blank', title : '',
callback : this._setFilter tooltip : 'Failed',
}, icon : 'icon-nd-download-failed',
{ callback : this._setFilter
key : 'grabbed', }, {
title : '', key : 'deleted',
tooltip : 'Grabbed', title : '',
icon : 'icon-nd-downloading', tooltip : 'Deleted',
callback : this._setFilter icon : 'icon-nd-deleted',
}, callback : this._setFilter
{ }]
key : 'imported', };
title : '', this.toolbar.show(new ToolbarLayout({
tooltip : 'Imported', right : [filterOptions],
icon : 'icon-nd-imported', context : this
callback : this._setFilter }));
}, },
{ _setFilter : function(buttonContext){
key : 'failed', var mode = buttonContext.model.get('key');
title : '', this.collection.state.currentPage = 1;
tooltip : 'Failed', var promise = this.collection.setFilterMode(mode);
icon : 'icon-nd-download-failed', if(buttonContext) {
callback : this._setFilter buttonContext.ui.icon.spinForPromise(promise);
}, }
{ }
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);
}
}
});
});

View File

@ -1,16 +1,12 @@
'use strict'; var Backbone = require('backbone');
define( var SeriesModel = require('../../Series/SeriesModel');
[ var EpisodeModel = require('../../Series/EpisodeModel');
'backbone',
'Series/SeriesModel', module.exports = Backbone.Model.extend({
'Series/EpisodeModel' parse : function(model){
], function (Backbone, SeriesModel, EpisodeModel) { model.series = new SeriesModel(model.series);
return Backbone.Model.extend({ model.episode = new EpisodeModel(model.episode);
parse: function (model) { model.episode.set('series', model.series);
model.series = new SeriesModel(model.series); return model;
model.episode = new EpisodeModel(model.episode); }
model.episode.set('series', model.series); });
return model;
}
});
});

View File

@ -1,36 +1,24 @@
'use strict'; var NzbDroneCell = require('../../Cells/NzbDroneCell');
define(
[
'Cells/NzbDroneCell'
], function (NzbDroneCell) {
return NzbDroneCell.extend({
className: 'history-quality-cell', module.exports = NzbDroneCell.extend({
className : 'history-quality-cell',
render: function () { render : function(){
var title = '';
var title = ''; var quality = this.model.get('quality');
var quality = this.model.get('quality'); var revision = quality.revision;
var revision = quality.revision; if(revision.real && revision.real > 0) {
title += ' REAL';
if (revision.real && revision.real > 0) { }
title += ' REAL'; if(revision.version && revision.version > 1) {
} title += ' PROPER';
}
if (revision.version && revision.version > 1) { title = title.trim();
title += ' PROPER'; if(this.model.get('qualityCutoffNotMet')) {
} this.$el.html('<span class="badge badge-inverse" title="{0}">{1}</span>'.format(title, quality.quality.name));
}
title = title.trim(); else {
this.$el.html('<span class="badge" title="{0}">{1}</span>'.format(title, quality.quality.name));
if (this.model.get('qualityCutoffNotMet')) { }
this.$el.html('<span class="badge badge-inverse" title="{0}">{1}</span>'.format(title, quality.quality.name)); return this;
} }
else { });
this.$el.html('<span class="badge" title="{0}">{1}</span>'.format(title, quality.quality.name));
}
return this;
}
});
});

View File

@ -1,29 +1,16 @@
'use strict'; var NzbDroneCell = require('../../Cells/NzbDroneCell');
define( module.exports = NzbDroneCell.extend({
[ className : 'progress-cell',
'Cells/NzbDroneCell' render : function(){
], function (NzbDroneCell) { this.$el.empty();
return NzbDroneCell.extend({ if(this.cellValue) {
var status = this.model.get('status').toLowerCase();
className: 'progress-cell', if(status === 'downloading') {
var progress = 100 - this.model.get('sizeleft') / this.model.get('size') * 100;
render: function () { 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));
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;
} }
}); }
}); return this;
}
});

View File

@ -1,31 +1,22 @@
'use strict'; var _ = require('underscore');
define( var Backbone = require('backbone');
[ var PageableCollection = require('backbone.pageable');
'underscore', var QueueModel = require('./QueueModel');
'backbone', require('../../Mixins/backbone.signalr.mixin');
'backbone.pageable',
'Activity/Queue/QueueModel',
'Mixins/backbone.signalr.mixin'
], function (_, Backbone, PageableCollection, QueueModel) {
var QueueCollection = PageableCollection.extend({
url : window.NzbDrone.ApiRoot + '/queue',
model: QueueModel,
state: { module.exports = (function(){
pageSize: 15 var QueueCollection = PageableCollection.extend({
}, url : window.NzbDrone.ApiRoot + '/queue',
model : QueueModel,
mode: 'client', state : {pageSize : 15},
mode : 'client',
findEpisode: function (episodeId) { findEpisode : function(episodeId){
return _.find(this.fullCollection.models, function (queueModel) { return _.find(this.fullCollection.models, function(queueModel){
return queueModel.get('episode').id === episodeId; return queueModel.get('episode').id === episodeId;
}); });
} }
});
var collection = new QueueCollection().bindSignalR();
collection.fetch();
return collection;
}); });
var collection = new QueueCollection().bindSignalR();
collection.fetch();
return collection;
}).call(this);

View File

@ -1,16 +1,12 @@
'use strict'; var Backbone = require('backbone');
define( var SeriesModel = require('../../Series/SeriesModel');
[ var EpisodeModel = require('../../Series/EpisodeModel');
'backbone',
'Series/SeriesModel', module.exports = Backbone.Model.extend({
'Series/EpisodeModel' parse : function(model){
], function (Backbone, SeriesModel, EpisodeModel) { model.series = new SeriesModel(model.series);
return Backbone.Model.extend({ model.episode = new EpisodeModel(model.episode);
parse: function (model) { model.episode.set('series', model.series);
model.series = new SeriesModel(model.series); return model;
model.episode = new EpisodeModel(model.episode); }
model.episode.set('series', model.series); });
return model;
}
});
});

View File

@ -1,89 +1,69 @@
'use strict'; var Marionette = require('marionette');
var NzbDroneCell = require('../../Cells/NzbDroneCell');
define( module.exports = NzbDroneCell.extend({
[ className : 'queue-status-cell',
'marionette', template : 'Activity/Queue/QueueStatusCellTemplate',
'Cells/NzbDroneCell' render : function(){
], function (Marionette, NzbDroneCell) { this.$el.empty();
return NzbDroneCell.extend({ if(this.cellValue) {
var status = this.cellValue.get('status').toLowerCase();
className : 'queue-status-cell', var trackedDownloadStatus = this.cellValue.has('trackedDownloadStatus') ? this.cellValue.get('trackedDownloadStatus').toLowerCase() : 'ok';
template : 'Activity/Queue/QueueStatusCellTemplate', var icon = 'icon-nd-downloading';
var title = 'Downloading';
render: function () { var itemTitle = this.cellValue.get('title');
this.$el.empty(); var content = itemTitle;
if(status === 'paused') {
if (this.cellValue) { icon = 'icon-pause';
var status = this.cellValue.get('status').toLowerCase(); title = 'Paused';
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;
} }
}); 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;
}
});

View File

@ -1,46 +1,33 @@
'use strict'; var _ = require('underscore');
define( var Marionette = require('marionette');
[ var QueueCollection = require('./QueueCollection');
'underscore',
'marionette',
'Activity/Queue/QueueCollection'
], function (_, Marionette, QueueCollection) {
return Marionette.ItemView.extend({
tagName: 'span',
initialize: function () { module.exports = Marionette.ItemView.extend({
this.listenTo(QueueCollection, 'sync', this.render); tagName : 'span',
QueueCollection.fetch(); initialize : function(){
}, this.listenTo(QueueCollection, 'sync', this.render);
QueueCollection.fetch();
render: function () { },
this.$el.empty(); render : function(){
this.$el.empty();
if (QueueCollection.length === 0) { if(QueueCollection.length === 0) {
return this; return this;
} }
var count = QueueCollection.fullCollection.length;
var count = QueueCollection.fullCollection.length; var label = 'label-info';
var label = 'label-info'; var errors = QueueCollection.fullCollection.some(function(model){
return model.has('trackedDownloadStatus') && model.get('trackedDownloadStatus').toLowerCase() === 'error';
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;
}
}); });
}); 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;
}
});

View File

@ -1,47 +1,32 @@
'use strict'; var NzbDroneCell = require('../../Cells/NzbDroneCell');
var fileSize = require('filesize');
define( var moment = require('moment');
[ var UiSettingsModel = require('../../Shared/UiSettingsModel');
'Cells/NzbDroneCell', var FormatHelpers = require('../../Shared/FormatHelpers');
'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));
}
}
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; 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;
}
});

View File

@ -1,27 +1,18 @@
'use strict'; var Backbone = require('backbone');
define( var SeriesModel = require('../Series/SeriesModel');
[ var _ = require('underscore');
'backbone',
'Series/SeriesModel',
'underscore'
], function (Backbone, SeriesModel, _) {
return Backbone.Collection.extend({
url : window.NzbDrone.ApiRoot + '/series/lookup',
model: SeriesModel,
parse: function (response) { module.exports = Backbone.Collection.extend({
url : window.NzbDrone.ApiRoot + '/series/lookup',
var self = this; model : SeriesModel,
parse : function(response){
_.each(response, function (model) { var self = this;
model.id = undefined; _.each(response, function(model){
model.id = undefined;
if (self.unmappedFolderModel) { if(self.unmappedFolderModel) {
model.path = self.unmappedFolderModel.get('folder').path; model.path = self.unmappedFolderModel.get('folder').path;
}
});
return response;
} }
}); });
}); return response;
}
});

View File

@ -1,67 +1,40 @@
'use strict'; var vent = require('../vent');
define( var AppLayout = require('../AppLayout');
[ var Marionette = require('marionette');
'vent', var RootFolderLayout = require('./RootFolders/RootFolderLayout');
'AppLayout', var ExistingSeriesCollectionView = require('./Existing/AddExistingSeriesCollectionView');
'marionette', var AddSeriesView = require('./AddSeriesView');
'AddSeries/RootFolders/RootFolderLayout', var ProfileCollection = require('../Profile/ProfileCollection');
'AddSeries/Existing/AddExistingSeriesCollectionView', var RootFolderCollection = require('./RootFolders/RootFolderCollection');
'AddSeries/AddSeriesView', require('../Series/SeriesCollection');
'Profile/ProfileCollection',
'AddSeries/RootFolders/RootFolderCollection',
'Series/SeriesCollection'
], function (vent,
AppLayout,
Marionette,
RootFolderLayout,
ExistingSeriesCollectionView,
AddSeriesView,
ProfileCollection,
RootFolderCollection) {
return Marionette.Layout.extend({ module.exports = Marionette.Layout.extend({
template: 'AddSeries/AddSeriesLayoutTemplate', template : 'AddSeries/AddSeriesLayoutTemplate',
regions : {workspace : '#add-series-workspace'},
regions: { events : {
workspace: '#add-series-workspace' 'click .x-import' : '_importSeries',
}, 'click .x-add-new' : '_addSeries'
},
events: { attributes : {id : 'add-series-screen'},
'click .x-import': '_importSeries', initialize : function(){
'click .x-add-new': '_addSeries' ProfileCollection.fetch();
}, RootFolderCollection.fetch().done(function(){
RootFolderCollection.synced = true;
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());
}
}); });
}); },
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());
}
});

View File

@ -1,174 +1,129 @@
'use strict'; var _ = require('underscore');
define( var vent = require('../vent');
[ var Marionette = require('marionette');
'underscore', var AddSeriesCollection = require('./AddSeriesCollection');
'vent', var SearchResultCollectionView = require('./SearchResultCollectionView');
'marionette', var EmptyView = require('./EmptyView');
'AddSeries/AddSeriesCollection', var NotFoundView = require('./NotFoundView');
'AddSeries/SearchResultCollectionView', var ErrorView = require('./ErrorView');
'AddSeries/EmptyView', var LoadingView = require('../Shared/LoadingView');
'AddSeries/NotFoundView',
'AddSeries/ErrorView',
'Shared/LoadingView'
], function (_, vent, Marionette, AddSeriesCollection, SearchResultCollectionView, EmptyView, NotFoundView, ErrorView, LoadingView) {
return Marionette.Layout.extend({
template: 'AddSeries/AddSeriesViewTemplate',
regions: { module.exports = Marionette.Layout.extend({
searchResult: '#search-result' template : 'AddSeries/AddSeriesViewTemplate',
}, regions : {searchResult : '#search-result'},
ui : {
ui: { seriesSearch : '.x-series-search',
seriesSearch: '.x-series-search', searchBar : '.x-search-bar',
searchBar : '.x-search-bar', loadMore : '.x-load-more'
loadMore : '.x-load-more' },
}, events : {"click .x-load-more" : '_onLoadMore'},
initialize : function(options){
events: { this.isExisting = options.isExisting;
'click .x-load-more': '_onLoadMore' this.collection = new AddSeriesCollection();
}, if(this.isExisting) {
this.collection.unmappedFolderModel = this.model;
initialize: function (options) { }
this.isExisting = options.isExisting; if(this.isExisting) {
this.collection = new AddSeriesCollection(); this.className = 'existing-series';
}
if (this.isExisting) { else {
this.collection.unmappedFolderModel = this.model; this.className = 'new-series';
} }
this.listenTo(vent, vent.Events.SeriesAdded, this._onSeriesAdded);
if (this.isExisting) { this.listenTo(this.collection, 'sync', this._showResults);
this.className = 'existing-series'; this.resultCollectionView = new SearchResultCollectionView({
} collection : this.collection,
else { isExisting : this.isExisting
this.className = 'new-series'; });
} this.throttledSearch = _.debounce(this.search, 1000, {trailing : true}).bind(this);
},
this.listenTo(vent, vent.Events.SeriesAdded, this._onSeriesAdded); onRender : function(){
this.listenTo(this.collection, 'sync', this._showResults); var self = this;
this.$el.addClass(this.className);
this.resultCollectionView = new SearchResultCollectionView({ this.ui.seriesSearch.keyup(function(e){
collection: this.collection, if(_.contains([9, 16, 17, 18, 19, 20, 33, 34, 35, 36, 37, 38, 39, 40, 91, 92, 93], e.keyCode)) {
isExisting: this.isExisting return;
}); }
self._abortExistingSearch();
this.throttledSearch = _.debounce(this.search, 1000, {trailing: true}).bind(this); self.throttledSearch({term : self.ui.seriesSearch.val()});
}, });
this._clearResults();
onRender: function () { if(this.isExisting) {
var self = this; this.ui.searchBar.hide();
}
this.$el.addClass(this.className); },
onShow : function(){
this.ui.seriesSearch.keyup(function (e) { this.ui.seriesSearch.focus();
},
//Ignore special keys: http://www.javascripter.net/faq/keycodes.htm search : function(options){
if (_.contains([9, 16, 17, 18, 19, 20, 33, 34, 35, 36, 37, 38, 39, 40, 91, 92, 93 ], e.keyCode)) { var self = this;
return; this.collection.reset();
} if(!options.term || options.term === this.collection.term) {
return Marionette.$.Deferred().resolve();
self._abortExistingSearch(); }
self.throttledSearch({ this.searchResult.show(new LoadingView());
term: self.ui.seriesSearch.val() this.collection.term = options.term;
}); this.currentSearchPromise = this.collection.fetch({data : {term : options.term}});
}); this.currentSearchPromise.fail(function(){
self._showError();
this._clearResults(); });
return this.currentSearchPromise;
if (this.isExisting) { },
this.ui.searchBar.hide(); _onSeriesAdded : function(options){
} if(this.isExisting && options.series.get('path') === this.model.get('folder').path) {
}, this.close();
}
onShow: function () { else if(!this.isExisting) {
this.ui.seriesSearch.focus(); this.collection.term = '';
}, this.collection.reset();
this._clearResults();
search: function (options) { this.ui.seriesSearch.val('');
var self = this; this.ui.seriesSearch.focus();
}
this.collection.reset(); },
_onLoadMore : function(){
if (!options.term || options.term === this.collection.term) { var showingAll = this.resultCollectionView.showMore();
return Marionette.$.Deferred().resolve(); this.ui.searchBar.show();
} if(showingAll) {
this.ui.loadMore.hide();
this.searchResult.show(new LoadingView()); }
this.collection.term = options.term; },
this.currentSearchPromise = this.collection.fetch({ _clearResults : function(){
data: { term: options.term } if(!this.isExisting) {
}); this.searchResult.show(new EmptyView());
}
this.currentSearchPromise.fail(function () { else {
self._showError(); this.searchResult.close();
}); }
},
return this.currentSearchPromise; _showResults : function(){
}, if(!this.isClosed) {
if(this.collection.length === 0) {
_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(); this.ui.searchBar.show();
this.searchResult.show(new NotFoundView({term : this.collection.term}));
if (showingAll) { }
this.ui.loadMore.hide(); else {
} this.searchResult.show(this.resultCollectionView);
}, if(!this.showingAll && this.isExisting) {
this.ui.loadMore.show();
_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 = '';
} }
} }
}); }
}); },
_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 = '';
}
}
});

View File

@ -1,11 +1,3 @@
'use strict'; var Marionette = require('marionette');
define( module.exports = Marionette.CompositeView.extend({template : 'AddSeries/EmptyViewTemplate'});
[
'marionette'
], function (Marionette) {
return Marionette.CompositeView.extend({
template: 'AddSeries/EmptyViewTemplate'
});
});

View File

@ -1,20 +1,11 @@
'use strict'; var Marionette = require('marionette');
define( module.exports = Marionette.CompositeView.extend({
[ template : 'AddSeries/ErrorViewTemplate',
'marionette' initialize : function(options){
], function (Marionette) { this.options = options;
},
return Marionette.CompositeView.extend({ templateHelpers : function(){
template: 'AddSeries/ErrorViewTemplate', return this.options;
}
initialize: function (options) { });
this.options = options;
},
templateHelpers: function () {
return this.options;
}
});
});

View File

@ -1,59 +1,38 @@
'use strict'; var Marionette = require('marionette');
define( var AddSeriesView = require('../AddSeriesView');
[ var UnmappedFolderCollection = require('./UnmappedFolderCollection');
'marionette',
'AddSeries/AddSeriesView',
'AddSeries/Existing/UnmappedFolderCollection'
], function (Marionette, AddSeriesView, UnmappedFolderCollection) {
return Marionette.CompositeView.extend({ module.exports = Marionette.CompositeView.extend({
itemView : AddSeriesView,
itemView : AddSeriesView, itemViewContainer : '.x-loading-folders',
itemViewContainer: '.x-loading-folders', template : 'AddSeries/Existing/AddExistingSeriesCollectionViewTemplate',
template : 'AddSeries/Existing/AddExistingSeriesCollectionViewTemplate', ui : {loadingFolders : '.x-loading-folders'},
initialize : function(){
ui: { this.collection = new UnmappedFolderCollection();
loadingFolders: '.x-loading-folders' this.collection.importItems(this.model);
}, },
showCollection : function(){
initialize: function () { this._showAndSearch(0);
this.collection = new UnmappedFolderCollection(); },
this.collection.importItems(this.model); appendHtml : function(collectionView, itemView, index){
}, collectionView.ui.loadingFolders.before(itemView.el);
},
showCollection: function () { _showAndSearch : function(index){
this._showAndSearch(0); var self = this;
}, var model = this.collection.at(index);
if(model) {
appendHtml: function(collectionView, itemView, index){ var currentIndex = index;
collectionView.ui.loadingFolders.before(itemView.el); var folderName = model.get('folder').name;
}, this.addItemView(model, this.getItemView(), index);
this.children.findByModel(model).search({term : folderName}).always(function(){
_showAndSearch: function (index) { if(!self.isClosed) {
var self = this; self._showAndSearch(currentIndex + 1);
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(); else {
} this.ui.loadingFolders.hide();
}, }
},
itemViewOptions: { itemViewOptions : {isExisting : true}
isExisting: true });
}
});
});

View File

@ -1,24 +1,17 @@
'use strict'; var Backbone = require('backbone');
define( var UnmappedFolderModel = require('./UnmappedFolderModel');
[ var _ = require('underscore');
'backbone',
'AddSeries/Existing/UnmappedFolderModel',
'underscore'
], function (Backbone, UnmappedFolderModel,_) {
return Backbone.Collection.extend({
model: UnmappedFolderModel,
importItems: function (rootFolderModel) { module.exports = Backbone.Collection.extend({
model : UnmappedFolderModel,
this.reset(); importItems : function(rootFolderModel){
var rootFolder = rootFolderModel; this.reset();
var rootFolder = rootFolderModel;
_.each(rootFolderModel.get('unmappedFolders'), function (folder) { _.each(rootFolderModel.get('unmappedFolders'), function(folder){
this.push(new UnmappedFolderModel({ this.push(new UnmappedFolderModel({
rootFolder: rootFolder, rootFolder : rootFolder,
folder : folder folder : folder
})); }));
}, this); }, this);
} }
}); });
});

View File

@ -1,10 +1,3 @@
'use strict'; var Backbone = require('backbone');
define( module.exports = Backbone.Model.extend({});
[
'backbone'
], function (Backbone) {
return Backbone.Model.extend({
});
});

View File

@ -1,20 +1,11 @@
'use strict'; var Marionette = require('marionette');
define( module.exports = Marionette.CompositeView.extend({
[ template : 'AddSeries/NotFoundViewTemplate',
'marionette' initialize : function(options){
], function (Marionette) { this.options = options;
},
return Marionette.CompositeView.extend({ templateHelpers : function(){
template: 'AddSeries/NotFoundViewTemplate', return this.options;
}
initialize: function (options) { });
this.options = options;
},
templateHelpers: function () {
return this.options;
}
});
});

View File

@ -1,17 +1,11 @@
'use strict'; var Backbone = require('backbone');
define( var RootFolderModel = require('./RootFolderModel');
[ require('../../Mixins/backbone.signalr.mixin');
'backbone',
'AddSeries/RootFolders/RootFolderModel',
'Mixins/backbone.signalr.mixin'
], function (Backbone, RootFolderModel) {
var RootFolderCollection = Backbone.Collection.extend({ module.exports = (function(){
url : window.NzbDrone.ApiRoot + '/rootfolder', var RootFolderCollection = Backbone.Collection.extend({
model: RootFolderModel url : window.NzbDrone.ApiRoot + '/rootfolder',
}); model : RootFolderModel
//var collection = new RootFolderCollection().bindSignalR();
return new RootFolderCollection();
}); });
return new RootFolderCollection();
}).call(this);

View File

@ -1,15 +1,8 @@
'use strict'; var Marionette = require('marionette');
var RootFolderItemView = require('./RootFolderItemView');
define( module.exports = Marionette.CompositeView.extend({
[ template : 'AddSeries/RootFolders/RootFolderCollectionViewTemplate',
'marionette', itemViewContainer : '.x-root-folders',
'AddSeries/RootFolders/RootFolderItemView' itemView : RootFolderItemView
], function (Marionette, RootFolderItemView) { });
return Marionette.CompositeView.extend({
template : 'AddSeries/RootFolders/RootFolderCollectionViewTemplate',
itemViewContainer : '.x-root-folders',
itemView : RootFolderItemView
});
});

View File

@ -1,37 +1,22 @@
'use strict'; var Marionette = require('marionette');
define( module.exports = Marionette.ItemView.extend({
[ template : 'AddSeries/RootFolders/RootFolderItemViewTemplate',
'marionette' tagName : 'tr',
], function (Marionette) { initialize : function(){
this.listenTo(this.model, 'change', this.render);
return Marionette.ItemView.extend({ },
events : {
template: 'AddSeries/RootFolders/RootFolderItemViewTemplate', 'click .x-delete' : 'removeFolder',
tagName : 'tr', 'click .x-folder' : 'folderSelected'
},
initialize: function () { removeFolder : function(){
this.listenTo(this.model, 'change', this.render); var self = this;
}, this.model.destroy().success(function(){
self.close();
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);
}
}); });
}); },
folderSelected : function(){
this.trigger('folderSelected', this.model);
}
});

View File

@ -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( module.exports = (function(){
[ var layout = Marionette.Layout.extend({
'marionette', template : 'AddSeries/RootFolders/RootFolderLayoutTemplate',
'AddSeries/RootFolders/RootFolderCollectionView', ui : {pathInput : '.x-path'},
'AddSeries/RootFolders/RootFolderCollection', regions : {currentDirs : '#current-dirs'},
'AddSeries/RootFolders/RootFolderModel', events : {
'Shared/LoadingView', 'click .x-add' : '_addFolder',
'Mixins/AsValidatedView', 'keydown .x-path input' : '_keydown'
'Mixins/FileBrowser' },
], function (Marionette, RootFolderCollectionView, RootFolderCollection, RootFolderModel, LoadingView, AsValidatedView) { initialize : function(){
this.collection = RootFolderCollection;
var layout = Marionette.Layout.extend({ this.rootfolderListView = new RootFolderCollectionView({collection : RootFolderCollection});
template: 'AddSeries/RootFolders/RootFolderLayoutTemplate', this.listenTo(this.rootfolderListView, 'itemview:folderSelected', this._onFolderSelected);
this.listenTo(RootFolderCollection, 'sync', this._showCurrentDirs);
ui: { },
pathInput: '.x-path' onRender : function(){
}, this.currentDirs.show(new LoadingView());
if(RootFolderCollection.synced) {
regions: { this._showCurrentDirs();
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();
} }
}); this.ui.pathInput.fileBrowser();
},
return AsValidatedView.apply(layout); _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);

View File

@ -1,12 +1,6 @@
'use strict'; var Backbone = require('backbone');
define(
[ module.exports = Backbone.Model.extend({
'backbone' urlRoot : window.NzbDrone.ApiRoot + '/rootfolder',
], function (Backbone) { defaults : {freeSpace : 0}
return Backbone.Model.extend({ });
urlRoot : window.NzbDrone.ApiRoot + '/rootfolder',
defaults: {
freeSpace: 0
}
});
});

View File

@ -1,35 +1,24 @@
'use strict'; var Marionette = require('marionette');
define( var SearchResultView = require('./SearchResultView');
[
'marionette',
'AddSeries/SearchResultView'
], function (Marionette, SearchResultView) {
return Marionette.CollectionView.extend({ module.exports = Marionette.CollectionView.extend({
itemView : SearchResultView,
itemView: SearchResultView, initialize : function(options){
this.isExisting = options.isExisting;
initialize: function (options) { this.showing = 1;
this.isExisting = options.isExisting; },
this.showing = 1; showAll : function(){
}, this.showingAll = true;
this.render();
showAll: function () { },
this.showingAll = true; showMore : function(){
this.render(); this.showing += 5;
}, this.render();
return this.showing >= this.collection.length;
showMore: function () { },
this.showing += 5; appendHtml : function(collectionView, itemView, index){
this.render(); if(!this.isExisting || index < this.showing || index === 0) {
collectionView.$el.append(itemView.el);
return this.showing >= this.collection.length; }
}, }
});
appendHtml: function (collectionView, itemView, index) {
if (!this.isExisting || index < this.showing || index === 0) {
collectionView.$el.append(itemView.el);
}
}
});
});

View File

@ -1,27 +1,22 @@
define( var Marionette = require('marionette');
[ var ModalRegion = require('./Shared/Modal/ModalRegion');
'marionette', var FileBrowserModalRegion = require('./Shared/FileBrowser/FileBrowserModalRegion');
'Shared/Modal/ModalRegion', var ControlPanelRegion = require('./Shared/ControlPanel/ControlPanelRegion');
'Shared/FileBrowser/FileBrowserModalRegion',
'Shared/ControlPanel/ControlPanelRegion'
], function (Marionette, ModalRegion, FileBrowserModalRegion, ControlPanelRegion) {
'use strict';
var Layout = Marionette.Layout.extend({ module.exports = (function(){
'use strict';
regions: { var Layout = Marionette.Layout.extend({
navbarRegion : '#nav-region', regions : {
mainRegion : '#main-region' navbarRegion : '#nav-region',
}, mainRegion : '#main-region'
},
initialize: function () { initialize : function(){
this.addRegions({ this.addRegions({
modalRegion : ModalRegion, modalRegion : ModalRegion,
fileBrowserModalRegion : FileBrowserModalRegion, fileBrowserModalRegion : FileBrowserModalRegion,
controlPanelRegion : ControlPanelRegion controlPanelRegion : ControlPanelRegion
}); });
} }
});
return new Layout({el: 'body'});
}); });
return new Layout({el : 'body'});
}).call(this);

View File

@ -1,25 +1,18 @@
'use strict'; var Marionette = require('marionette');
define( var StatusModel = require('../System/StatusModel');
[ require('../Mixins/CopyToClipboard');
'marionette',
'System/StatusModel',
'Mixins/CopyToClipboard'
], function (Marionette, StatusModel) {
return Marionette.Layout.extend({
template: 'Calendar/CalendarFeedViewTemplate',
ui: { module.exports = Marionette.Layout.extend({
icalUrl : '.x-ical-url', template : 'Calendar/CalendarFeedViewTemplate',
icalCopy : '.x-ical-copy' 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, templateHelpers : {
icalWebCalUrl : 'webcal://' + window.location.host + StatusModel.get('urlBase') + '/feed/calendar/NzbDrone.ics?apikey=' + window.NzbDrone.ApiKey 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 () { onShow : function(){
this.ui.icalCopy.copyToClipboard(this.ui.icalUrl); this.ui.icalCopy.copyToClipboard(this.ui.icalUrl);
} }
}); });
});

View File

@ -1,40 +1,28 @@
'use strict'; var AppLayout = require('../AppLayout');
define( var Marionette = require('marionette');
[ var UpcomingCollectionView = require('./UpcomingCollectionView');
'AppLayout', var CalendarView = require('./CalendarView');
'marionette', var CalendarFeedView = require('./CalendarFeedView');
'Calendar/UpcomingCollectionView',
'Calendar/CalendarView',
'Calendar/CalendarFeedView'
], function (AppLayout, Marionette, UpcomingCollectionView, CalendarView, CalendarFeedView) {
return Marionette.Layout.extend({
template: 'Calendar/CalendarLayoutTemplate',
regions: { module.exports = Marionette.Layout.extend({
upcoming: '#x-upcoming', template : 'Calendar/CalendarLayoutTemplate',
calendar: '#x-calendar' regions : {
}, upcoming : '#x-upcoming',
calendar : '#x-calendar'
events: { },
'click .x-ical': '_showiCal' events : {"click .x-ical" : '_showiCal'},
}, onShow : function(){
this._showUpcoming();
onShow: function () { this._showCalendar();
this._showUpcoming(); },
this._showCalendar(); _showUpcoming : function(){
}, this.upcoming.show(new UpcomingCollectionView());
},
_showUpcoming: function () { _showCalendar : function(){
this.upcoming.show(new UpcomingCollectionView()); this.calendar.show(new CalendarView());
}, },
_showiCal : function(){
_showCalendar: function () { var view = new CalendarFeedView();
this.calendar.show(new CalendarView()); AppLayout.modalRegion.show(view);
}, }
});
_showiCal: function () {
var view = new CalendarFeedView();
AppLayout.modalRegion.show(view);
}
});
});

View File

@ -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( module.exports = Marionette.ItemView.extend({
[ storageKey : 'calendar.view',
'jquery', initialize : function(){
'vent', this.collection = new CalendarCollection().bindSignalR({updateOnly : true});
'marionette', this.listenTo(this.collection, 'change', this._reloadCalendarEvents);
'moment', this.listenTo(QueueCollection, 'sync', this._reloadCalendarEvents);
'Calendar/Collection', },
'Shared/UiSettingsModel', render : function(){
'Activity/Queue/QueueCollection', this.$el.empty().fullCalendar(this._getOptions());
'Config', },
'Mixins/backbone.signalr.mixin', onShow : function(){
'fullcalendar', this.$('.fc-button-today').click();
'jquery.easypiechart' },
], function ($, vent, Marionette, moment, CalendarCollection, UiSettings, QueueCollection, Config) { _viewRender : function(view){
if($(window).width() < 768) {
return Marionette.ItemView.extend({ this.$('.fc-header-title').show();
storageKey: 'calendar.view', this.$('.calendar-title').remove();
var title = this.$('.fc-header-title').text();
initialize: function () { var titleDiv = '<div class="calendar-title"><h2>{0}</h2></div>'.format(title);
this.collection = new CalendarCollection().bindSignalR({ updateOnly: true }); this.$('.fc-header').before(titleDiv);
this.listenTo(this.collection, 'change', this._reloadCalendarEvents); this.$('.fc-header-title').hide();
this.listenTo(QueueCollection, 'sync', this._reloadCalendarEvents); }
}, if(Config.getValue(this.storageKey) !== view.name) {
Config.setValue(this.storageKey, view.name);
render : function () { }
this.$el.empty().fullCalendar(this._getOptions()); this._getEvents(view);
}, },
_eventRender : function(event, element){
onShow: function () { this.$(element).addClass(event.statusLevel);
this.$('.fc-button-today').click(); this.$(element).children('.fc-event-inner').addClass(event.statusLevel);
}, if(event.downloading) {
var progress = 100 - event.downloading.get('sizeleft') / event.downloading.get('size') * 100;
_viewRender: function (view) { var releaseTitle = event.downloading.get('title');
var estimatedCompletionTime = moment(event.downloading.get('estimatedCompletionTime')).fromNow();
if ($(window).width() < 768) { var status = event.downloading.get('status').toLocaleLowerCase();
this.$('.fc-header-title').show(); var errorMessage = event.downloading.get('errorMessage');
this.$('.calendar-title').remove(); if(status === 'pending') {
this._addStatusIcon(element, 'icon-time', 'Release will be processed {0}'.format(estimatedCompletionTime));
var title = this.$('.fc-header-title').text(); }
var titleDiv = '<div class="calendar-title"><h2>{0}</h2></div>'.format(title); else if(errorMessage) {
if(status === 'completed') {
this.$('.fc-header').before(titleDiv); this._addStatusIcon(element, 'icon-nd-import-failed', 'Import failed: {0}'.format(errorMessage));
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));
}
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 { else {
options.defaultView = Config.getValue(this.storageKey, 'basicWeek'); this._addStatusIcon(element, 'icon-nd-download-failed', 'Download failed: {0}'.format(errorMessage));
options.header = {
left : 'prev,next today',
center: 'title',
right : 'month,basicWeek,basicDay'
};
} }
}
options.titleFormat = { else if(status === 'failed') {
month : 'MMMM YYYY', this._addStatusIcon(element, 'icon-nd-download-failed', 'Download failed: check download client for more details');
week : UiSettings.get('shortDateFormat'), }
day : UiSettings.get('longDateFormat') else if(status === 'warning') {
}; this._addStatusIcon(element, 'icon-nd-download-warning', 'Download warning: check download client for more details');
}
options.columnFormat = { else {
month : 'ddd', // Mon this.$(element).find('.fc-event-time').after('<span class="chart pull-right" data-percent="{0}"></span>'.format(progress));
week : UiSettings.get('calendarWeekColumnHeader'), this.$(element).find('.chart').easyPieChart({
day : 'dddd' // Monday barColor : '#ffffff',
}; trackColor : false,
scaleColor : false,
options.timeFormat = { lineWidth : 2,
'default': UiSettings.get('timeFormat') size : 14,
}; animate : false
});
return options; this.$(element).find('.chart').tooltip({
}, title : 'Episode is downloading - {0}% {1}'.format(progress.toFixed(1), releaseTitle),
container : '.fc-content'
_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'
}); });
} }
}
},
_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'
});
}
});

View File

@ -1,17 +1,12 @@
'use strict'; var Backbone = require('backbone');
define( var EpisodeModel = require('../Series/EpisodeModel');
[
'backbone',
'Series/EpisodeModel'
], function (Backbone, EpisodeModel) {
return Backbone.Collection.extend({
url : window.NzbDrone.ApiRoot + '/calendar',
model: EpisodeModel,
comparator: function (model) { module.exports = Backbone.Collection.extend({
var date = new Date(model.get('airDateUtc')); url : window.NzbDrone.ApiRoot + '/calendar',
var time = date.getTime(); model : EpisodeModel,
return time; comparator : function(model){
} var date = new Date(model.get('airDateUtc'));
}); var time = date.getTime();
}); return time;
}
});

View File

@ -1,32 +1,23 @@
'use strict'; var Backbone = require('backbone');
define( var moment = require('moment');
[ var EpisodeModel = require('../Series/EpisodeModel');
'backbone',
'moment',
'Series/EpisodeModel'
], function (Backbone, moment, EpisodeModel) {
return Backbone.Collection.extend({
url : window.NzbDrone.ApiRoot + '/calendar',
model: EpisodeModel,
comparator: function (model1, model2) { module.exports = Backbone.Collection.extend({
var airDate1 = model1.get('airDateUtc'); url : window.NzbDrone.ApiRoot + '/calendar',
var date1 = moment(airDate1); model : EpisodeModel,
var time1 = date1.unix(); comparator : function(model1, model2){
var airDate1 = model1.get('airDateUtc');
var airDate2 = model2.get('airDateUtc'); var date1 = moment(airDate1);
var date2 = moment(airDate2); var time1 = date1.unix();
var time2 = date2.unix(); var airDate2 = model2.get('airDateUtc');
var date2 = moment(airDate2);
if (time1 < time2){ var time2 = date2.unix();
return -1; if(time1 < time2) {
} return -1;
}
if (time1 > time2){ if(time1 > time2) {
return 1; return 1;
} }
return 0;
return 0; }
} });
});
});

View File

@ -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( module.exports = Marionette.CollectionView.extend({
[ itemView : UpcomingItemView,
'underscore', initialize : function(){
'marionette', this.collection = new UpcomingCollection().bindSignalR({updateOnly : true});
'Calendar/UpcomingCollection', this.collection.fetch();
'Calendar/UpcomingItemView', this._fetchCollection = _.bind(this._fetchCollection, this);
'Mixins/backbone.signalr.mixin' this.timer = window.setInterval(this._fetchCollection, 60 * 60 * 1000);
], function (_, Marionette, UpcomingCollection, UpcomingItemView) { },
return Marionette.CollectionView.extend({ onClose : function(){
itemView: UpcomingItemView, window.clearInterval(this.timer);
},
initialize: function () { _fetchCollection : function(){
this.collection = new UpcomingCollection().bindSignalR({ updateOnly: true }); this.collection.fetch();
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();
}
});
});

View File

@ -1,33 +1,19 @@
'use strict'; var vent = require('../vent');
var Marionette = require('marionette');
var moment = require('moment');
define( module.exports = Marionette.ItemView.extend({
[ template : 'Calendar/UpcomingItemViewTemplate',
'vent', tagName : 'div',
'marionette', events : {"click .x-episode-title" : '_showEpisodeDetails'},
'moment' initialize : function(){
], function (vent, Marionette, moment) { var start = this.model.get('airDateUtc');
return Marionette.ItemView.extend({ var runtime = this.model.get('series').runtime;
template: 'Calendar/UpcomingItemViewTemplate', var end = moment(start).add('minutes', runtime);
tagName : 'div', this.model.set({end : end.toISOString()});
this.listenTo(this.model, 'change', this.render);
events: { },
'click .x-episode-title': '_showEpisodeDetails' _showEpisodeDetails : function(){
}, vent.trigger(vent.Commands.ShowEpisodeDetails, {episode : this.model});
}
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});
}
});
});

View File

@ -1,39 +1,26 @@
'use strict'; var Backgrid = require('backgrid');
define( var Marionette = require('marionette');
[ require('bootstrap');
'backgrid',
'marionette',
'bootstrap'
], function (Backgrid, Marionette) {
return Backgrid.Cell.extend({ module.exports = Backgrid.Cell.extend({
className : 'approval-status-cell',
className: 'approval-status-cell', template : 'Cells/ApprovalStatusCellTemplate',
template : 'Cells/ApprovalStatusCellTemplate', render : function(){
var rejections = this.model.get(this.column.get('name'));
render: function () { if(rejections.length === 0) {
return this;
var rejections = this.model.get(this.column.get('name')); }
this.templateFunction = Marionette.TemplateCache.get(this.template);
if (rejections.length === 0) { var html = this.templateFunction(rejections);
return this; this.$el.html('<i class="icon-exclamation-sign"/>');
} this.$el.popover({
content : html,
this.templateFunction = Marionette.TemplateCache.get(this.template); html : true,
trigger : 'hover',
var html = this.templateFunction(rejections); title : 'Release Rejected',
this.$el.html('<i class="icon-exclamation-sign"/>'); placement : 'left',
container : this.$el
this.$el.popover({
content : html,
html : true,
trigger : 'hover',
title : 'Release Rejected',
placement: 'left',
container: this.$el
});
return this;
}
}); });
}); return this;
}
});

View File

@ -1,33 +1,20 @@
'use strict'; var vent = require('../vent');
define( var Backgrid = require('backgrid');
[
'vent',
'backgrid'
], function (vent, Backgrid) {
return Backgrid.Cell.extend({
className : 'delete-episode-file-cell', module.exports = Backgrid.Cell.extend({
className : 'delete-episode-file-cell',
events: { events : {"click" : '_onClick'},
'click': '_onClick' render : function(){
}, this.$el.empty();
this.$el.html('<i class="icon-nd-delete"></i>');
render: function () { return this;
this.$el.empty(); },
this.$el.html('<i class="icon-nd-delete"></i>'); _onClick : function(){
var self = this;
return 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});
_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 });
});
}
}
});
});

View File

@ -1,78 +1,59 @@
'use strict'; var Backgrid = require('backgrid');
define( var Marionette = require('marionette');
[ var _ = require('underscore');
'backgrid', var ProfileSchemaCollection = require('../../Settings/Profile/ProfileSchemaCollection');
'marionette',
'underscore',
'Settings/Profile/ProfileSchemaCollection'
], function (Backgrid, Marionette, _, ProfileSchemaCollection) {
return Backgrid.CellEditor.extend({
className: 'quality-cell-editor', module.exports = Backgrid.CellEditor.extend({
template : 'Cells/Edit/QualityCellEditorTemplate', className : 'quality-cell-editor',
tagName : 'select', template : 'Cells/Edit/QualityCellEditorTemplate',
tagName : 'select',
events: { events : {
'change' : 'save', "change" : 'save',
'blur' : 'close', "blur" : 'close',
'keydown': 'close' "keydown" : 'close'
}, },
render : function(){
render: function () { var self = this;
var self = this; var profileSchemaCollection = new ProfileSchemaCollection();
var promise = profileSchemaCollection.fetch();
var profileSchemaCollection = new ProfileSchemaCollection(); promise.done(function(){
var promise = profileSchemaCollection.fetch(); var templateName = self.template;
self.schema = profileSchemaCollection.first();
promise.done(function () { var selected = _.find(self.schema.get('items'), function(model){
var templateName = self.template; return model.quality.id === self.model.get(self.column.get('name')).quality.id;
self.schema = profileSchemaCollection.first(); });
if(selected) {
var selected = _.find(self.schema.get('items'), function (model) { selected.quality.selected = true;
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);
} }
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);
}
});

View File

@ -1,49 +1,37 @@
'use strict'; var vent = require('../vent');
var NzbDroneCell = require('./NzbDroneCell');
var CommandController = require('../Commands/CommandController');
define( module.exports = NzbDroneCell.extend({
[ className : 'episode-actions-cell',
'vent', events : {
'Cells/NzbDroneCell', "click .x-automatic-search" : '_automaticSearch',
'Commands/CommandController' "click .x-manual-search" : '_manualSearch'
], function (vent, NzbDroneCell, CommandController) { },
return NzbDroneCell.extend({ render : function(){
this.$el.empty();
className: 'episode-actions-cell', 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({
events: { element : this.$el.find('.x-automatic-search'),
'click .x-automatic-search' : '_automaticSearch', command : {
'click .x-manual-search' : '_manualSearch' name : 'episodeSearch',
}, episodeIds : [this.model.get('id')]
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' });
} }
}); });
}); 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'
});
}
});

View File

@ -1,63 +1,42 @@
'use strict'; var _ = require('underscore');
var ToggleCell = require('./ToggleCell');
var SeriesCollection = require('../Series/SeriesCollection');
var Messenger = require('../Shared/Messenger');
define( module.exports = ToggleCell.extend({
[ className : 'toggle-cell episode-monitored',
'underscore', _originalOnClick : ToggleCell.prototype._onClick,
'Cells/ToggleCell', _onClick : function(e){
'Series/SeriesCollection', var series = SeriesCollection.get(this.model.get('seriesId'));
'Shared/Messenger' if(!series.get('monitored')) {
], function (_, ToggleCell, SeriesCollection, Messenger) { Messenger.show({
return ToggleCell.extend({ message : 'Unable to change monitored state when series is not monitored',
type : 'error'
className: 'toggle-cell episode-monitored', });
return;
_originalOnClick: ToggleCell.prototype._onClick, }
if(e.shiftKey && this.model.episodeCollection.lastToggled) {
_onClick: function (e) { this._selectRange();
return;
var series = SeriesCollection.get(this.model.get('seriesId')); }
this._originalOnClick.apply(this, arguments);
if (!series.get('monitored')) { this.model.episodeCollection.lastToggled = this.model;
},
Messenger.show({ _selectRange : function(){
message: 'Unable to change monitored state when series is not monitored', var episodeCollection = this.model.episodeCollection;
type : 'error' var lastToggled = episodeCollection.lastToggled;
}); var currentIndex = episodeCollection.indexOf(this.model);
var lastIndex = episodeCollection.indexOf(lastToggled);
return; var low = Math.min(currentIndex, lastIndex);
} var high = Math.max(currentIndex, lastIndex);
var range = _.range(low + 1, high);
if (e.shiftKey && this.model.episodeCollection.lastToggled) { _.each(range, function(index){
this._selectRange(); var model = episodeCollection.at(index);
model.set('monitored', lastToggled.get('monitored'));
return; model.save();
}
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;
}
}); });
}); this.model.set('monitored', lastToggled.get('monitored'));
this.model.save();
this.model.episodeCollection.lastToggled = undefined;
}
});

View File

@ -1,79 +1,58 @@
'use strict'; var NzbDroneCell = require('./NzbDroneCell');
var FormatHelpers = require('../Shared/FormatHelpers');
var _ = require('underscore');
define( module.exports = NzbDroneCell.extend({
[ className : 'episode-number-cell',
'Cells/NzbDroneCell', render : function(){
'Shared/FormatHelpers', this.$el.empty();
'underscore' var airDateField = this.column.get('airDateUtc') || 'airDateUtc';
], function (NzbDroneCell, FormatHelpers, _) { var seasonField = this.column.get('seasonNumber') || 'seasonNumber';
return NzbDroneCell.extend({ var episodeField = this.column.get('episodes') || 'episodeNumber';
var absoluteEpisodeField = 'absoluteEpisodeNumber';
className: 'episode-number-cell', if(this.model) {
var result = 'Unknown';
render: function () { var airDate = this.model.get(airDateField);
var seasonNumber = this.model.get(seasonField);
this.$el.empty(); var episodes = this.model.get(episodeField);
var absoluteEpisodeNumber = this.model.get(absoluteEpisodeField);
var airDateField = this.column.get('airDateUtc') || 'airDateUtc'; if(this.cellValue) {
var seasonField = this.column.get('seasonNumber') || 'seasonNumber'; if(!seasonNumber) {
var episodeField = this.column.get('episodes') || 'episodeNumber'; seasonNumber = this.cellValue.get(seasonField);
var absoluteEpisodeField = 'absoluteEpisodeNumber'; }
if(!episodes) {
if (this.model) { episodes = this.cellValue.get(episodeField);
var result = 'Unknown'; }
if(absoluteEpisodeNumber === undefined) {
var airDate = this.model.get(airDateField); absoluteEpisodeNumber = this.cellValue.get(absoluteEpisodeField);
var seasonNumber = this.model.get(seasonField); }
var episodes = this.model.get(episodeField); if(!airDate) {
var absoluteEpisodeNumber = this.model.get(absoluteEpisodeField); this.model.get(airDateField);
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);
} }
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;
}
});

View File

@ -1,33 +1,21 @@
'use strict'; var Marionette = require('marionette');
var NzbDroneCell = require('./NzbDroneCell');
define( module.exports = NzbDroneCell.extend({
[ className : 'episode-progress-cell',
'marionette', template : 'Cells/EpisodeProgressCellTemplate',
'Cells/NzbDroneCell' render : function(){
], function (Marionette, NzbDroneCell) { var episodeCount = this.model.get('episodeCount');
return NzbDroneCell.extend({ var episodeFileCount = this.model.get('episodeFileCount');
className: 'episode-progress-cell', var percent = 100;
template : 'Cells/EpisodeProgressCellTemplate', if(episodeCount > 0) {
percent = episodeFileCount / episodeCount * 100;
render: function () { }
this.model.set('percentOfEpisodes', percent);
var episodeCount = this.model.get('episodeCount'); this.templateFunction = Marionette.TemplateCache.get(this.template);
var episodeFileCount = this.model.get('episodeFileCount'); var data = this.model.toJSON();
var html = this.templateFunction(data);
var percent = 100; this.$el.html(html);
return this;
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;
}
});
});

View File

@ -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( module.exports = NzbDroneCell.extend({
[ className : 'episode-status-cell',
'reqres', render : function(){
'backbone', this.listenTo(QueueCollection, 'sync', this._renderCell);
'Cells/NzbDroneCell', this._renderCell();
'Activity/Queue/QueueCollection', return this;
'moment', },
'Shared/FormatHelpers' _renderCell : function(){
], function (reqres, Backbone, NzbDroneCell, QueueCollection, moment, FormatHelpers) { if(this.episodeFile) {
return NzbDroneCell.extend({ this.stopListening(this.episodeFile, 'change', this._refresh);
}
className: 'episode-status-cell', this.$el.empty();
if(this.model) {
render: function () { var icon;
this.listenTo(QueueCollection, 'sync', this._renderCell); var tooltip;
var hasAired = moment(this.model.get('airDateUtc')).isBefore(moment());
this._renderCell(); this.episodeFile = this._getFile();
if(this.episodeFile) {
return this; this.listenTo(this.episodeFile, 'change', this._refresh);
}, var quality = this.episodeFile.get('quality');
var revision = quality.revision;
_renderCell: function () { var size = FormatHelpers.bytes(this.episodeFile.get('size'));
var title = 'Episode downloaded';
if (this.episodeFile) { if(revision.real && revision.real > 0) {
this.stopListening(this.episodeFile, 'change', this._refresh); title += '[REAL]';
} }
if(revision.version && revision.version > 1) {
this.$el.empty(); title += ' [PROPER]';
}
if (this.model) { if(size !== '') {
title += ' - {0}'.format(size);
var icon; }
var tooltip; if(this.episodeFile.get('qualityCutoffNotMet')) {
this.$el.html('<span class="badge badge-inverse" title="{0}">{1}</span>'.format(title, quality.quality.name));
var hasAired = moment(this.model.get('airDateUtc')).isBefore(moment()); }
this.episodeFile = this._getFile(); else {
this.$el.html('<span class="badge" title="{0}">{1}</span>'.format(title, quality.quality.name));
if (this.episodeFile) { }
this.listenTo(this.episodeFile, 'change', this._refresh); return;
}
var quality = this.episodeFile.get('quality'); else {
var revision = quality.revision; var model = this.model;
var size = FormatHelpers.bytes(this.episodeFile.get('size')); var downloading = QueueCollection.findEpisode(model.get('id'));
var title = 'Episode downloaded'; if(downloading) {
var progress = 100 - downloading.get('sizeleft') / downloading.get('size') * 100;
if (revision.real && revision.real > 0) { if(progress === 0) {
title += '[REAL]'; icon = 'icon-nd-downloading';
} tooltip = 'Episode is downloading';
}
if (revision.version && revision.version > 1) { else {
title += ' [PROPER]'; 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));
}
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; 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));
} }
}, else if(this.model.get('grabbed')) {
icon = 'icon-nd-downloading';
_getFile: function () { tooltip = 'Episode is downloading';
var hasFile = this.model.get('hasFile'); }
else if(!this.model.get('airDateUtc')) {
if (hasFile) { icon = 'icon-nd-tba';
var episodeFile; tooltip = 'TBA';
}
if (reqres.hasHandler(reqres.Requests.GetEpisodeFileById)) { else if(hasAired) {
episodeFile = reqres.request(reqres.Requests.GetEpisodeFileById, this.model.get('episodeFileId')); icon = 'icon-nd-missing';
} tooltip = 'Episode missing from disk';
}
else if (this.model.has('episodeFile')) { else {
episodeFile = new Backbone.Model(this.model.get('episodeFile')); icon = 'icon-nd-not-aired';
} tooltip = 'Episode has not aired';
if (episodeFile) {
return episodeFile;
}
} }
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;
}
});

View File

@ -1,33 +1,22 @@
'use strict'; var vent = require('../vent');
var NzbDroneCell = require('./NzbDroneCell');
define( module.exports = NzbDroneCell.extend({
[ className : 'episode-title-cell',
'vent', events : {"click" : '_showDetails'},
'Cells/NzbDroneCell' render : function(){
], function (vent, NzbDroneCell) { var title = this.cellValue.get('title');
return NzbDroneCell.extend({ if(!title || title === '') {
title = 'TBA';
className: 'episode-title-cell', }
this.$el.html(title);
events: { return this;
'click': '_showDetails' },
}, _showDetails : function(){
var hideSeriesLink = this.column.get('hideSeriesLink');
render: function () { vent.trigger(vent.Commands.ShowEpisodeDetails, {
var title = this.cellValue.get('title'); episode : this.cellValue,
hideSeriesLink : hideSeriesLink
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 });
}
}); });
}); }
});

View File

@ -1,52 +1,39 @@
'use strict'; var NzbDroneCell = require('./NzbDroneCell');
define( module.exports = NzbDroneCell.extend({
[ className : 'history-event-type-cell',
'Cells/NzbDroneCell' render : function(){
], function (NzbDroneCell) { this.$el.empty();
return NzbDroneCell.extend({ if(this.cellValue) {
var icon;
className: 'history-event-type-cell', var toolTip;
switch (this.cellValue.get('eventType')) {
render: function () { case 'grabbed':
this.$el.empty(); icon = 'icon-nd-downloading';
toolTip = 'Episode grabbed from {0} and sent to download client'.format(this.cellValue.get('data').indexer);
if (this.cellValue) { break;
case 'seriesFolderImported':
var icon; icon = 'icon-hdd';
var toolTip; toolTip = 'Existing episode file added to library';
break;
switch (this.cellValue.get('eventType')) { case 'downloadFolderImported':
case 'grabbed': icon = 'icon-nd-imported';
icon = 'icon-nd-downloading'; toolTip = 'Episode downloaded successfully and picked up from download client';
toolTip = 'Episode grabbed from {0} and sent to download client'.format(this.cellValue.get('data').indexer); break;
break; case 'downloadFailed':
case 'seriesFolderImported': icon = 'icon-nd-download-failed';
icon = 'icon-hdd'; toolTip = 'Episode download failed';
toolTip = 'Existing episode file added to library'; break;
break; case 'episodeFileDeleted':
case 'downloadFolderImported': icon = 'icon-nd-deleted';
icon = 'icon-nd-imported'; toolTip = 'Episode file deleted';
toolTip = 'Episode downloaded successfully and picked up from download client'; break;
break; default:
case 'downloadFailed': icon = 'icon-question';
icon = 'icon-nd-download-failed'; toolTip = 'unknown event';
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;
} }
}); this.$el.html('<i class="{0}" title="{1}" data-placement="right"/>'.format(icon, toolTip));
}); }
return this;
}
});

View File

@ -1,19 +1,12 @@
'use strict'; var Backgrid = require('backgrid');
var FormatHelpers = require('../Shared/FormatHelpers');
define( module.exports = Backgrid.Cell.extend({
[ className : 'file-size-cell',
'backgrid', render : function(){
'Shared/FormatHelpers' var size = this.model.get(this.column.get('name'));
], function (Backgrid, FormatHelpers) { this.$el.html(FormatHelpers.bytes(size));
return Backgrid.Cell.extend({ this.delegateEvents();
return this;
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;
}
});
});

View File

@ -1,16 +1,10 @@
'use strict'; var Backgrid = require('backgrid');
define(
[
'backgrid'
], function (Backgrid) {
return Backgrid.Cell.extend({
className : 'indexer-cell', module.exports = Backgrid.Cell.extend({
className : 'indexer-cell',
render: function () { render : function(){
var indexer = this.model.get(this.column.get('name')); var indexer = this.model.get(this.column.get('name'));
this.$el.html(indexer); this.$el.html(indexer);
return this; return this;
} }
}); });
});

View File

@ -1,63 +1,42 @@
'use strict'; var Backgrid = require('backgrid');
var Backbone = require('backbone');
define( module.exports = Backgrid.Cell.extend({
[ _originalInit : Backgrid.Cell.prototype.initialize,
'backgrid', initialize : function(){
'backbone' this._originalInit.apply(this, arguments);
], function (Backgrid, Backbone) { this.cellValue = this._getValue();
return Backgrid.Cell.extend({ this.listenTo(this.model, 'change', this._refresh);
if(this._onEdit) {
_originalInit: Backgrid.Cell.prototype.initialize, this.listenTo(this.model, 'backgrid:edit', function(model, column, cell, editor){
if(column.get('name') === this.column.get('name')) {
initialize: function () { this._onEdit(model, column, cell, editor);
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(); _refresh : function(){
this.render(); this.cellValue = this._getValue();
}, this.render();
},
_getValue: function () { _getValue : function(){
var cellValue = this.column.get('cellValue');
var cellValue = this.column.get('cellValue'); if(cellValue) {
if(cellValue === 'this') {
if (cellValue) { return this.model;
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;
} }
}
}); 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;
}
});

View File

@ -1,25 +1,16 @@
'use strict'; var Backgrid = require('backgrid');
define( var ProfileCollection = require('../Profile/ProfileCollection');
[ var _ = require('underscore');
'backgrid',
'Profile/ProfileCollection',
'underscore'
], function (Backgrid, ProfileCollection,_) {
return Backgrid.Cell.extend({
className: 'profile-cell',
render: function () { module.exports = Backgrid.Cell.extend({
className : 'profile-cell',
this.$el.empty(); render : function(){
var profileId = this.model.get(this.column.get('name')); this.$el.empty();
var profileId = this.model.get(this.column.get('name'));
var profile = _.findWhere(ProfileCollection.models, { id: profileId }); var profile = _.findWhere(ProfileCollection.models, {id : profileId});
if(profile) {
if (profile) { this.$el.html(profile.get('name'));
this.$el.html(profile.get('name')); }
} return this;
}
return this; });
}
});
});

View File

@ -1,13 +1,8 @@
'use strict'; var TemplatedCell = require('./TemplatedCell');
define( var QualityCellEditor = require('./Edit/QualityCellEditor');
[
'Cells/TemplatedCell',
'Cells/Edit/QualityCellEditor'
], function (TemplatedCell, QualityCellEditor) {
return TemplatedCell.extend({
className: 'quality-cell', module.exports = TemplatedCell.extend({
template : 'Cells/QualityCellTemplate', className : 'quality-cell',
editor : QualityCellEditor template : 'Cells/QualityCellTemplate',
}); editor : QualityCellEditor
}); });

View File

@ -1,37 +1,25 @@
'use strict'; var NzbDroneCell = require('./NzbDroneCell');
define( var moment = require('moment');
[ var FormatHelpers = require('../Shared/FormatHelpers');
'Cells/NzbDroneCell', var UiSettings = require('../Shared/UiSettingsModel');
'moment',
'Shared/FormatHelpers',
'Shared/UiSettingsModel'
], function (NzbDroneCell, moment, FormatHelpers, UiSettings) {
return NzbDroneCell.extend({
className: 'relative-date-cell', module.exports = NzbDroneCell.extend({
className : 'relative-date-cell',
render: function () { render : function(){
var dateStr = this.model.get(this.column.get('name'));
var dateStr = this.model.get(this.column.get('name')); if(dateStr) {
var date = moment(dateStr);
if (dateStr) { var result = '<span title="{0}">{1}</span>';
var date = moment(dateStr); var tooltip = date.format(UiSettings.longDateTime());
var result = '<span title="{0}">{1}</span>'; var text;
var tooltip = date.format(UiSettings.longDateTime()); if(UiSettings.get('showRelativeDates')) {
var text; text = FormatHelpers.relativeDate(dateStr);
if (UiSettings.get('showRelativeDates')) {
text = FormatHelpers.relativeDate(dateStr);
}
else {
text = date.format(UiSettings.get('shortDateFormat'));
}
this.$el.html(result.format(tooltip, text));
}
return this;
} }
}); else {
}); text = date.format(UiSettings.get('shortDateFormat'));
}
this.$el.html(result.format(tooltip, text));
}
return this;
}
});

View File

@ -1,37 +1,25 @@
'use strict'; var NzbDroneCell = require('./NzbDroneCell');
define( var moment = require('moment');
[ var FormatHelpers = require('../Shared/FormatHelpers');
'Cells/NzbDroneCell', var UiSettings = require('../Shared/UiSettingsModel');
'moment',
'Shared/FormatHelpers',
'Shared/UiSettingsModel'
], function (NzbDroneCell, moment, FormatHelpers, UiSettings) {
return NzbDroneCell.extend({
className: 'relative-time-cell', module.exports = NzbDroneCell.extend({
className : 'relative-time-cell',
render: function () { render : function(){
var dateStr = this.model.get(this.column.get('name'));
var dateStr = this.model.get(this.column.get('name')); if(dateStr) {
var date = moment(dateStr);
if (dateStr) { var result = '<span title="{0}">{1}</span>';
var date = moment(dateStr); var tooltip = date.format(UiSettings.longDateTime());
var result = '<span title="{0}">{1}</span>'; var text;
var tooltip = date.format(UiSettings.longDateTime()); if(UiSettings.get('showRelativeDates')) {
var text; text = date.fromNow();
if (UiSettings.get('showRelativeDates')) {
text = date.fromNow();
}
else {
text = date.format(UiSettings.shortDateTime());
}
this.$el.html(result.format(tooltip, text));
}
return this;
} }
}); else {
}); text = date.format(UiSettings.shortDateTime());
}
this.$el.html(result.format(tooltip, text));
}
return this;
}
});

View File

@ -1,28 +1,17 @@
'use strict'; var NzbDroneCell = require('./NzbDroneCell');
define( module.exports = NzbDroneCell.extend({
[ className : 'release-title-cell',
'Cells/NzbDroneCell' render : function(){
], function (NzbDroneCell) { this.$el.empty();
return NzbDroneCell.extend({ var title = this.model.get('title');
var infoUrl = this.model.get('infoUrl');
className: 'release-title-cell', if(infoUrl) {
this.$el.html('<a href="{0}">{1}</a>'.format(infoUrl, title));
render: function () { }
this.$el.empty(); else {
this.$el.html(title);
var title = this.model.get('title'); }
var infoUrl = this.model.get('infoUrl'); return this;
}
if (infoUrl) { });
this.$el.html('<a href="{0}">{1}</a>'.format(infoUrl, title));
}
else {
this.$el.html(title);
}
return this;
}
});
});

View File

@ -1,19 +1,11 @@
'use strict'; var Backgrid = require('backgrid');
define(
[
'backgrid'
], function (Backgrid) {
return Backgrid.Cell.extend({
className : 'season-folder-cell', module.exports = Backgrid.Cell.extend({
className : 'season-folder-cell',
render: function () { render : function(){
this.$el.empty(); this.$el.empty();
var seasonFolder = this.model.get(this.column.get('name'));
var seasonFolder = this.model.get(this.column.get('name')); this.$el.html(seasonFolder.toString());
this.$el.html(seasonFolder.toString()); return this;
}
return this; });
}
});
});

View File

@ -1,49 +1,35 @@
'use strict'; var $ = require('jquery');
define( var _ = require('underscore');
[ var BackgridSelectAll = require('backgrid.selectall');
'jquery',
'underscore',
'backgrid.selectall'
], function ($, _, BackgridSelectAll) {
return BackgridSelectAll.extend({
enterEditMode: function (e) { module.exports = BackgridSelectAll.extend({
if (e.shiftKey && this.model.collection.lastToggled) { enterEditMode : function(e){
this._selectRange(); if(e.shiftKey && this.model.collection.lastToggled) {
} this._selectRange();
}
var checked = $(e.target).prop('checked'); var checked = $(e.target).prop('checked');
this.model.collection.lastToggled = this.model;
this.model.collection.lastToggled = this.model; this.model.collection.checked = checked;
this.model.collection.checked = checked; },
}, onChange : function(e){
var checked = $(e.target).prop('checked');
onChange: function (e) { this.$el.parent().toggleClass('selected', checked);
var checked = $(e.target).prop('checked'); this.model.trigger('backgrid:selected', this.model, 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;
_selectRange: function () { var checked = collection.checked;
var collection = this.model.collection; var currentIndex = collection.indexOf(this.model);
var lastToggled = collection.lastToggled; var lastIndex = collection.indexOf(lastToggled);
var checked = collection.checked; var low = Math.min(currentIndex, lastIndex);
var high = Math.max(currentIndex, lastIndex);
var currentIndex = collection.indexOf(this.model); var range = _.range(low + 1, high);
var lastIndex = collection.indexOf(lastToggled); _.each(range, function(index){
var model = collection.at(index);
var low = Math.min(currentIndex, lastIndex); model.trigger('backgrid:select', model, checked);
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;
}
}); });
}); this.model.collection.lastToggled = undefined;
this.model.collection.checked = undefined;
}
});

View File

@ -1,53 +1,34 @@
'use strict'; var vent = require('../vent');
var NzbDroneCell = require('./NzbDroneCell');
var CommandController = require('../Commands/CommandController');
define( module.exports = NzbDroneCell.extend({
[ className : 'series-actions-cell',
'vent', ui : {refresh : '.x-refresh'},
'Cells/NzbDroneCell', events : {
'Commands/CommandController' "click .x-edit" : '_editSeries',
], function (vent, NzbDroneCell, CommandController) { "click .x-refresh" : '_refreshSeries'
return NzbDroneCell.extend({ },
render : function(){
className: 'series-actions-cell', 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>');
ui: { CommandController.bindToCommand({
refresh: '.x-refresh' element : this.$el.find('.x-refresh'),
}, command : {
name : 'refreshSeries',
events: { seriesId : this.model.get('id')
'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
});
} }
}); });
}); 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
});
}
});

View File

@ -1,36 +1,26 @@
'use strict'; var NzbDroneCell = require('./NzbDroneCell');
define(
[
'Cells/NzbDroneCell'
], function (NzbDroneCell) {
return NzbDroneCell.extend({
className: 'series-status-cell',
render: function () { module.exports = NzbDroneCell.extend({
this.$el.empty(); className : 'series-status-cell',
var monitored = this.model.get('monitored'); render : function(){
var status = this.model.get('status'); this.$el.empty();
var monitored = this.model.get('monitored');
if (status === 'ended') { var status = this.model.get('status');
this.$el.html('<i class="icon-stop grid-icon" title="Ended"></i>'); if(status === 'ended') {
this._setStatusWeight(3); this.$el.html('<i class="icon-stop grid-icon" title="Ended"></i>');
} this._setStatusWeight(3);
}
else if (!monitored) { else if(!monitored) {
this.$el.html('<i class="icon-pause grid-icon" title="Not Monitored"></i>'); this.$el.html('<i class="icon-pause grid-icon" title="Not Monitored"></i>');
this._setStatusWeight(2); this._setStatusWeight(2);
} }
else {
else { this.$el.html('<i class="icon-play grid-icon" title="Continuing"></i>');
this.$el.html('<i class="icon-play grid-icon" title="Continuing"></i>'); this._setStatusWeight(1);
this._setStatusWeight(1); }
} return this;
},
return this; _setStatusWeight : function(weight){
}, this.model.set('statusWeight', weight, {silent : true});
}
_setStatusWeight: function (weight) { });
this.model.set('statusWeight', weight, {silent: true});
}
});
});

View File

@ -1,12 +1,6 @@
'use strict'; var TemplatedCell = require('./TemplatedCell');
define(
[
'Cells/TemplatedCell'
], function (TemplatedCell) {
return TemplatedCell.extend({
className: 'series-title-cell', module.exports = TemplatedCell.extend({
template : 'Cells/SeriesTitleTemplate' className : 'series-title-cell',
template : 'Cells/SeriesTitleTemplate'
}); });
});

View File

@ -1,23 +1,14 @@
'use strict'; var Marionette = require('marionette');
var NzbDroneCell = require('./NzbDroneCell');
define( module.exports = NzbDroneCell.extend({
[ render : function(){
'marionette', var templateName = this.column.get('template') || this.template;
'Cells/NzbDroneCell' this.templateFunction = Marionette.TemplateCache.get(templateName);
], function (Marionette, NzbDroneCell) { var data = this.cellValue.toJSON();
return NzbDroneCell.extend({ var html = this.templateFunction(data);
this.$el.html(html);
render: function () { this.delegateEvents();
return this;
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;
}
});
});

View File

@ -1,53 +1,32 @@
'use strict'; var Backgrid = require('backgrid');
define( module.exports = Backgrid.Cell.extend({
[ className : 'toggle-cell',
'backgrid' events : {"click" : '_onClick'},
], function (Backgrid) { _onClick : function(){
return Backgrid.Cell.extend({ var self = this;
this.$el.tooltip('hide');
className: 'toggle-cell', var name = this.column.get('name');
this.model.set(name, !this.model.get(name));
events: { this.$('i').addClass('icon-spinner icon-spin');
'click': '_onClick' this.model.save().always(function(){
}, self.render();
_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;
}
}); });
}); },
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;
}
});

View File

@ -1,26 +1,18 @@
'use strict'; var Backbone = require('backbone');
define( var CommandModel = require('./CommandModel');
[ require('../Mixins/backbone.signalr.mixin');
'backbone',
'Commands/CommandModel',
'Mixins/backbone.signalr.mixin'
], function (Backbone, CommandModel) {
var CommandCollection = Backbone.Collection.extend({ module.exports = (function(){
url : window.NzbDrone.ApiRoot + '/command', var CommandCollection = Backbone.Collection.extend({
model: CommandModel, url : window.NzbDrone.ApiRoot + '/command',
model : CommandModel,
findCommand: function (command) { findCommand : function(command){
return this.find(function (model) { return this.find(function(model){
return model.isSameCommand(command); return model.isSameCommand(command);
}); });
} }
});
var collection = new CommandCollection().bindSignalR();
collection.fetch();
return collection;
}); });
var collection = new CommandCollection().bindSignalR();
collection.fetch();
return collection;
}).call(this);

View File

@ -1,98 +1,75 @@
'use strict'; var vent = require('../vent');
define( var CommandModel = require('./CommandModel');
[ var CommandCollection = require('./CommandCollection');
'vent', var CommandMessengerCollectionView = require('./CommandMessengerCollectionView');
'Commands/CommandModel', var _ = require('underscore');
'Commands/CommandCollection', var moment = require('moment');
'Commands/CommandMessengerCollectionView', var Messenger = require('../Shared/Messenger');
'underscore', require('../jQuery/jquery.spin');
'moment',
'Shared/Messenger',
'jQuery/jquery.spin'
], function (vent, CommandModel, CommandCollection, CommandMessengerCollectionView, _, moment, Messenger) {
module.exports = (function(){
CommandMessengerCollectionView.render(); CommandMessengerCollectionView.render();
var singleton = function(){
var singleton = function () { return {
_lastCommand : {},
return { Execute : function(name, properties){
var attr = _.extend({name : name.toLocaleLowerCase()}, properties);
_lastCommand: {}, var commandModel = new CommandModel(attr);
if(this._lastCommand.command && this._lastCommand.command.isSameCommand(attr) && moment().add('seconds', -5).isBefore(this._lastCommand.time)) {
Execute: function (name, properties) { Messenger.show({
message : 'Please wait at least 5 seconds before running this command again',
var attr = _.extend({name: name.toLocaleLowerCase()}, properties); hideAfter : 5,
var commandModel = new CommandModel(attr); type : 'error'
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);
}); });
return this._lastCommand.promise;
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();
} }
}; 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);

View File

@ -1,14 +1,8 @@
'use strict'; var Marionette = require('marionette');
define( var commandCollection = require('./CommandCollection');
[ var CommandMessengerItemView = require('./CommandMessengerItemView');
'marionette',
'Commands/CommandCollection',
'Commands/CommandMessengerItemView'
], function (Marionette, commandCollection, CommandMessengerItemView) {
var CollectionView = Marionette.CollectionView.extend({ module.exports = (function(){
itemView: CommandMessengerItemView var CollectionView = Marionette.CollectionView.extend({itemView : CommandMessengerItemView});
}); return new CollectionView({collection : commandCollection});
}).call(this);
return new CollectionView({collection: commandCollection});
});

View File

@ -1,51 +1,37 @@
'use strict'; var Marionette = require('marionette');
define( var Messenger = require('../Shared/Messenger');
[
'marionette',
'Shared/Messenger'
], function ( Marionette, Messenger) {
return Marionette.ItemView.extend({ module.exports = Marionette.ItemView.extend({
initialize : function(){
initialize: function () { this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'change', this.render); },
}, render : function(){
if(!this.model.get('message') || !this.model.get('sendUpdatesToClient')) {
render: function () { return;
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')),
var message = { id : this.model.id,
type : 'info', hideAfter : 0
message : '[{0}] {1}'.format(this.model.get('name'), this.model.get('message')), };
id : this.model.id, switch (this.model.get('state')) {
hideAfter: 0 case 'completed':
}; message.hideAfter = 4;
break;
switch (this.model.get('state')) { case 'failed':
case 'completed': message.hideAfter = 4;
message.hideAfter = 4; message.type = 'error';
break; break;
case 'failed': default:
message.hideAfter = 4; message.hideAfter = 0;
message.type = 'error'; }
break; if(this.messenger) {
default : this.messenger.update(message);
message.hideAfter = 0; }
} else {
this.messenger = Messenger.show(message);
if (this.messenger) { }
this.messenger.update(message); console.log(message.message);
} }
});
else {
this.messenger = Messenger.show(message);
}
console.log(message.message);
}
});
});

View File

@ -1,46 +1,34 @@
'use strict'; var _ = require('underscore');
define( var Backbone = require('backbone');
[
'underscore',
'backbone'
], function (_, Backbone) {
return Backbone.Model.extend({
url: window.NzbDrone.ApiRoot + '/command',
parse: function (response) { module.exports = Backbone.Model.extend({
response.name = response.name.toLocaleLowerCase(); url : window.NzbDrone.ApiRoot + '/command',
return response; parse : function(response){
}, response.name = response.name.toLocaleLowerCase();
return response;
isSameCommand: function (command) { },
isSameCommand : function(command){
if (command.name.toLocaleLowerCase() !== this.get('name').toLocaleLowerCase()) { if(command.name.toLocaleLowerCase() !== this.get('name').toLocaleLowerCase()) {
return false; return false;
} }
for (var key in command) {
for (var key in command) { if(key !== 'name') {
if (key !== 'name') { if(Array.isArray(command[key])) {
if (Array.isArray(command[key])) { if(_.difference(command[key], this.get(key)).length > 0) {
if (_.difference(command[key], this.get(key)).length > 0) { return false;
return false;
}
}
else if (command[key] !== this.get(key)) {
return false;
}
} }
} }
else if(command[key] !== this.get(key)) {
return true; return false;
}, }
isActive: function () {
return this.get('state') !== 'completed' && this.get('state') !== 'failed';
},
isComplete: function () {
return this.get('state') === 'completed';
} }
}); }
}); return true;
},
isActive : function(){
return this.get('state') !== 'completed' && this.get('state') !== 'failed';
},
isComplete : function(){
return this.get('state') === 'completed';
}
});

View File

@ -1,77 +1,51 @@
'use strict'; var NzbDroneController = require('./Shared/NzbDroneController');
define( var AppLayout = require('./AppLayout');
[ var Marionette = require('marionette');
'Shared/NzbDroneController', var ActivityLayout = require('./Activity/ActivityLayout');
'AppLayout', var SettingsLayout = require('./Settings/SettingsLayout');
'marionette', var AddSeriesLayout = require('./AddSeries/AddSeriesLayout');
'Activity/ActivityLayout', var WantedLayout = require('./Wanted/WantedLayout');
'Settings/SettingsLayout', var CalendarLayout = require('./Calendar/CalendarLayout');
'AddSeries/AddSeriesLayout', var ReleaseLayout = require('./Release/ReleaseLayout');
'Wanted/WantedLayout', var SystemLayout = require('./System/SystemLayout');
'Calendar/CalendarLayout', var SeasonPassLayout = require('./SeasonPass/SeasonPassLayout');
'Release/ReleaseLayout', var SeriesEditorLayout = require('./Series/Editor/SeriesEditorLayout');
'System/SystemLayout',
'SeasonPass/SeasonPassLayout',
'Series/Editor/SeriesEditorLayout'
], function (NzbDroneController,
AppLayout,
Marionette,
ActivityLayout,
SettingsLayout,
AddSeriesLayout,
WantedLayout,
CalendarLayout,
ReleaseLayout,
SystemLayout,
SeasonPassLayout,
SeriesEditorLayout) {
return NzbDroneController.extend({
addSeries: function (action) { module.exports = NzbDroneController.extend({
this.setTitle('Add Series'); addSeries : function(action){
this.showMainRegion(new AddSeriesLayout({action: action})); this.setTitle('Add Series');
}, this.showMainRegion(new AddSeriesLayout({action : action}));
},
calendar: function () { calendar : function(){
this.setTitle('Calendar'); this.setTitle('Calendar');
this.showMainRegion(new CalendarLayout()); this.showMainRegion(new CalendarLayout());
}, },
settings : function(action){
settings: function (action) { this.setTitle('Settings');
this.setTitle('Settings'); this.showMainRegion(new SettingsLayout({action : action}));
this.showMainRegion(new SettingsLayout({ action: action })); },
}, wanted : function(action){
this.setTitle('Wanted');
wanted: function (action) { this.showMainRegion(new WantedLayout({action : action}));
this.setTitle('Wanted'); },
activity : function(action){
this.showMainRegion(new WantedLayout({ action: action })); this.setTitle('Activity');
}, this.showMainRegion(new ActivityLayout({action : action}));
},
activity: function (action) { rss : function(){
this.setTitle('Activity'); this.setTitle('RSS');
this.showMainRegion(new ReleaseLayout());
this.showMainRegion(new ActivityLayout({ action: action })); },
}, system : function(action){
this.setTitle('System');
rss: function () { this.showMainRegion(new SystemLayout({action : action}));
this.setTitle('RSS'); },
this.showMainRegion(new ReleaseLayout()); seasonPass : function(){
}, this.setTitle('Season Pass');
this.showMainRegion(new SeasonPassLayout());
system: function (action) { },
this.setTitle('System'); seriesEditor : function(){
this.showMainRegion(new SystemLayout({ action: action })); this.setTitle('Series Editor');
}, this.showMainRegion(new SeriesEditorLayout());
}
seasonPass: function () { });
this.setTitle('Season Pass');
this.showMainRegion(new SeasonPassLayout());
},
seriesEditor: function () {
this.setTitle('Series Editor');
this.showMainRegion(new SeriesEditorLayout());
}
});
});

View File

@ -1,41 +1,25 @@
'use strict'; var $ = require('jquery');
var vent = require('../../vent');
var Marionette = require('marionette');
var NzbDroneCell = require('../../Cells/NzbDroneCell');
define( module.exports = NzbDroneCell.extend({
[ className : 'episode-actions-cell',
'jquery', events : {"click .x-failed" : '_markAsFailed'},
'vent', render : function(){
'marionette', this.$el.empty();
'Cells/NzbDroneCell' if(this.model.get('eventType') === 'grabbed') {
], function ($, vent, Marionette, NzbDroneCell) { this.$el.html('<i class="icon-nd-delete x-failed" title="Mark download as failed"></i>');
return NzbDroneCell.extend({ }
return this;
className: 'episode-actions-cell', },
_markAsFailed : function(){
events: { var url = window.NzbDrone.ApiRoot + '/history/failed';
'click .x-failed' : '_markAsFailed' var data = {id : this.model.get('id')};
}, $.ajax({
url : url,
render: function () { type : 'POST',
this.$el.empty(); data : data
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
});
}
}); });
}); }
});

View File

@ -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( module.exports = NzbDroneCell.extend({
[ className : 'episode-activity-details-cell',
'jquery', render : function(){
'vent', this.$el.empty();
'marionette', this.$el.html('<i class="icon-info-sign"></i>');
'Cells/NzbDroneCell', var html = new HistoryDetailsView({model : this.model}).render().$el;
'Activity/History/Details/HistoryDetailsView', this.$el.popover({
'bootstrap' content : html,
], function ($, vent, Marionette, NzbDroneCell, HistoryDetailsView) { html : true,
return NzbDroneCell.extend({ trigger : 'hover',
title : 'Details',
className: 'episode-activity-details-cell', placement : 'left',
container : this.$el
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;
}
}); });
}); return this;
}
});

View File

@ -1,96 +1,68 @@
'use strict'; var Marionette = require('marionette');
define( var Backgrid = require('backgrid');
[ var HistoryCollection = require('../../Activity/History/HistoryCollection');
'marionette', var EventTypeCell = require('../../Cells/EventTypeCell');
'backgrid', var QualityCell = require('../../Cells/QualityCell');
'Activity/History/HistoryCollection', var RelativeDateCell = require('../../Cells/RelativeDateCell');
'Cells/EventTypeCell', var EpisodeActivityActionsCell = require('./EpisodeActivityActionsCell');
'Cells/QualityCell', var EpisodeActivityDetailsCell = require('./EpisodeActivityDetailsCell');
'Cells/RelativeDateCell', var NoActivityView = require('./NoActivityView');
'Episode/Activity/EpisodeActivityActionsCell', var LoadingView = require('../../Shared/LoadingView');
'Episode/Activity/EpisodeActivityDetailsCell',
'Episode/Activity/NoActivityView',
'Shared/LoadingView'
], function (Marionette,
Backgrid,
HistoryCollection,
EventTypeCell,
QualityCell,
RelativeDateCell,
EpisodeActivityActionsCell,
EpisodeActivityDetailsCell,
NoActivityView,
LoadingView) {
return Marionette.Layout.extend({ module.exports = Marionette.Layout.extend({
template: 'Episode/Activity/EpisodeActivityLayoutTemplate', template : 'Episode/Activity/EpisodeActivityLayoutTemplate',
regions : {activityTable : '.activity-table'},
regions: { columns : [{
activityTable: '.activity-table' name : 'eventType',
}, label : '',
cell : EventTypeCell,
columns: cellValue : 'this'
[ }, {
{ name : 'sourceTitle',
name : 'eventType', label : 'Source Title',
label : '', cell : 'string'
cell : EventTypeCell, }, {
cellValue: 'this' name : 'quality',
}, label : 'Quality',
{ cell : QualityCell
name : 'sourceTitle', }, {
label: 'Source Title', name : 'date',
cell : 'string' label : 'Date',
}, cell : RelativeDateCell
{ }, {
name : 'quality', name : 'this',
label: 'Quality', label : '',
cell : QualityCell cell : EpisodeActivityDetailsCell,
}, sortable : false
{ }, {
name : 'date', name : 'this',
label: 'Date', label : '',
cell : RelativeDateCell cell : EpisodeActivityActionsCell,
}, sortable : false
{ }],
name : 'this', initialize : function(options){
label : '', this.model = options.model;
cell : EpisodeActivityDetailsCell, this.series = options.series;
sortable: false this.collection = new HistoryCollection({
}, episodeId : this.model.id,
{ tableName : 'episodeActivity'
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());
}
}
}); });
}); 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());
}
}
});

View File

@ -1,11 +1,3 @@
'use strict'; var Marionette = require('marionette');
define(
[
'marionette'
], function (Marionette) {
return Marionette.ItemView.extend({ module.exports = Marionette.ItemView.extend({template : 'Episode/Activity/NoActivityViewTemplate'});
template: 'Episode/Activity/NoActivityViewTemplate'
});
});

View File

@ -1,130 +1,104 @@
'use strict'; var Marionette = require('marionette');
define( var SummaryLayout = require('./Summary/EpisodeSummaryLayout');
[ var SearchLayout = require('./Search/EpisodeSearchLayout');
'marionette', var EpisodeActivityLayout = require('./Activity/EpisodeActivityLayout');
'Episode/Summary/EpisodeSummaryLayout', var SeriesCollection = require('../Series/SeriesCollection');
'Episode/Search/EpisodeSearchLayout', var Messenger = require('../Shared/Messenger');
'Episode/Activity/EpisodeActivityLayout',
'Series/SeriesCollection',
'Shared/Messenger'
], function (Marionette, SummaryLayout, SearchLayout, EpisodeActivityLayout, SeriesCollection, Messenger) {
return Marionette.Layout.extend({ module.exports = Marionette.Layout.extend({
className : 'modal-lg', className : 'modal-lg',
template : 'Episode/EpisodeDetailsLayoutTemplate', template : 'Episode/EpisodeDetailsLayoutTemplate',
regions : {
regions: { summary : '#episode-summary',
summary : '#episode-summary', activity : '#episode-activity',
activity: '#episode-activity', search : '#episode-search'
search : '#episode-search' },
}, ui : {
summary : '.x-episode-summary',
ui: { activity : '.x-episode-activity',
summary : '.x-episode-summary', search : '.x-episode-search',
activity : '.x-episode-activity', monitored : '.x-episode-monitored'
search : '.x-episode-search', },
monitored: '.x-episode-monitored' events : {
}, "click .x-episode-summary" : '_showSummary',
"click .x-episode-activity" : '_showActivity',
events: { "click .x-episode-search" : '_showSearch',
"click .x-episode-monitored" : '_toggleMonitored'
'click .x-episode-summary' : '_showSummary', },
'click .x-episode-activity' : '_showActivity', templateHelpers : {},
'click .x-episode-search' : '_showSearch', initialize : function(options){
'click .x-episode-monitored': '_toggleMonitored' this.templateHelpers.hideSeriesLink = options.hideSeriesLink;
}, this.series = SeriesCollection.get(this.model.get('seriesId'));
this.templateHelpers.series = this.series.toJSON();
templateHelpers: {}, this.openingTab = options.openingTab || 'summary';
this.listenTo(this.model, 'sync', this._setMonitoredState);
initialize: function (options) { },
this.templateHelpers.hideSeriesLink = options.hideSeriesLink; onShow : function(){
this.searchLayout = new SearchLayout({model : this.model});
this.series = SeriesCollection.get(this.model.get('seriesId')); if(this.openingTab === 'search') {
this.templateHelpers.series = this.series.toJSON(); this.searchLayout.startManualSearch = true;
this.openingTab = options.openingTab || 'summary'; this._showSearch();
}
this.listenTo(this.model, 'sync', this._setMonitoredState); else {
}, this._showSummary();
}
onShow: function () { this._setMonitoredState();
this.searchLayout = new SearchLayout({ model: this.model }); if(this.series.get('monitored')) {
this.$el.removeClass('series-not-monitored');
if (this.openingTab === 'search') { }
this.searchLayout.startManualSearch = true; else {
this._showSearch(); this.$el.addClass('series-not-monitored');
} }
},
else { _showSummary : function(e){
this._showSummary(); if(e) {
} e.preventDefault();
}
this._setMonitoredState(); this.ui.summary.tab('show');
this.summary.show(new SummaryLayout({
if (this.series.get('monitored')) { model : this.model,
this.$el.removeClass('series-not-monitored'); series : this.series
} }));
},
else { _showActivity : function(e){
this.$el.addClass('series-not-monitored'); if(e) {
} e.preventDefault();
}, }
this.ui.activity.tab('show');
_showSummary: function (e) { this.activity.show(new EpisodeActivityLayout({
if (e) { model : this.model,
e.preventDefault(); series : this.series
} }));
},
this.ui.summary.tab('show'); _showSearch : function(e){
this.summary.show(new SummaryLayout({model: this.model, series: this.series})); if(e) {
}, e.preventDefault();
}
_showActivity: function (e) { this.ui.search.tab('show');
if (e) { this.search.show(this.searchLayout);
e.preventDefault(); },
} _toggleMonitored : function(){
if(!this.series.get('monitored')) {
this.ui.activity.tab('show'); Messenger.show({
this.activity.show(new EpisodeActivityLayout({model: this.model, series: this.series})); message : 'Unable to change monitored state when series is not monitored',
}, type : 'error'
});
_showSearch: function (e) { return;
if (e) { }
e.preventDefault(); var name = 'monitored';
} this.model.set(name, !this.model.get(name), {silent : true});
this.ui.monitored.addClass('icon-spinner icon-spin');
this.ui.search.tab('show'); this.model.save();
this.search.show(this.searchLayout); },
}, _setMonitoredState : function(){
this.ui.monitored.removeClass('icon-spin icon-spinner');
_toggleMonitored: function () { if(this.model.get('monitored')) {
if (!this.series.get('monitored')) { this.ui.monitored.addClass('icon-bookmark');
this.ui.monitored.removeClass('icon-bookmark-empty');
Messenger.show({ }
message: 'Unable to change monitored state when series is not monitored', else {
type : 'error' this.ui.monitored.addClass('icon-bookmark-empty');
}); this.ui.monitored.removeClass('icon-bookmark');
}
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');
}
}
});
});

View File

@ -1,10 +1,3 @@
'use strict'; var Marionette = require('marionette');
define(
[
'marionette'
], function (Marionette) {
return Marionette.ItemView.extend({ module.exports = Marionette.ItemView.extend({template : 'Episode/Search/ButtonsViewTemplate'});
template: 'Episode/Search/ButtonsViewTemplate'
});
});

View File

@ -1,88 +1,63 @@
'use strict'; var vent = require('../../vent');
define( var Marionette = require('marionette');
[ var ButtonsView = require('./ButtonsView');
'vent', var ManualSearchLayout = require('./ManualLayout');
'marionette', var ReleaseCollection = require('../../Release/ReleaseCollection');
'Episode/Search/ButtonsView', var SeriesCollection = require('../../Series/SeriesCollection');
'Episode/Search/ManualLayout', var CommandController = require('../../Commands/CommandController');
'Release/ReleaseCollection', var LoadingView = require('../../Shared/LoadingView');
'Series/SeriesCollection', var NoResultsView = require('./NoResultsView');
'Commands/CommandController',
'Shared/LoadingView',
'Episode/Search/NoResultsView'
], function (vent, Marionette, ButtonsView, ManualSearchLayout, ReleaseCollection, SeriesCollection,CommandController, LoadingView, NoResultsView) {
return Marionette.Layout.extend({ module.exports = Marionette.Layout.extend({
template: 'Episode/Search/EpisodeSearchLayoutTemplate', template : 'Episode/Search/EpisodeSearchLayoutTemplate',
regions : {main : '#episode-search-region'},
regions: { events : {
main: '#episode-search-region' "click .x-search-auto" : '_searchAuto',
}, "click .x-search-manual" : '_searchManual',
"click .x-search-back" : '_showButtons'
events: { },
'click .x-search-auto' : '_searchAuto', initialize : function(){
'click .x-search-manual': '_searchManual', this.mainView = new ButtonsView();
'click .x-search-back' : '_showButtons' this.releaseCollection = new ReleaseCollection();
}, this.listenTo(this.releaseCollection, 'sync', this._showSearchResults);
},
initialize: function () { onShow : function(){
this.mainView = new ButtonsView(); if(this.startManualSearch) {
this.releaseCollection = new ReleaseCollection(); this._searchManual();
}
this.listenTo(this.releaseCollection, 'sync', this._showSearchResults); else {
}, this._showMainView();
}
onShow: function () { },
if (this.startManualSearch) { _searchAuto : function(e){
this._searchManual(); if(e) {
} e.preventDefault();
}
else { CommandController.Execute('episodeSearch', {episodeIds : [this.model.get('id')]});
this._showMainView(); vent.trigger(vent.Commands.CloseModalCommand);
} },
}, _searchManual : function(e){
if(e) {
_searchAuto: function (e) { e.preventDefault();
if (e) { }
e.preventDefault(); this.mainView = new LoadingView();
} this._showMainView();
this.releaseCollection.fetchEpisodeReleases(this.model.id);
CommandController.Execute('episodeSearch', { },
episodeIds: [ this.model.get('id') ] _showMainView : function(){
}); this.main.show(this.mainView);
},
vent.trigger(vent.Commands.CloseModalCommand); _showButtons : function(){
}, this.mainView = new ButtonsView();
this._showMainView();
_searchManual: function (e) { },
if (e) { _showSearchResults : function(){
e.preventDefault(); if(this.releaseCollection.length === 0) {
} this.mainView = new NoResultsView();
}
this.mainView = new LoadingView(); else {
this._showMainView(); this.mainView = new ManualSearchLayout({collection : this.releaseCollection});
this.releaseCollection.fetchEpisodeReleases(this.model.id); }
}, this._showMainView();
}
_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();
}
});
});

View File

@ -1,86 +1,64 @@
'use strict'; var Marionette = require('marionette');
define( var Backgrid = require('backgrid');
[ var ReleaseTitleCell = require('../../Cells/ReleaseTitleCell');
'marionette', var FileSizeCell = require('../../Cells/FileSizeCell');
'backgrid', var QualityCell = require('../../Cells/QualityCell');
'Cells/ReleaseTitleCell', var ApprovalStatusCell = require('../../Cells/ApprovalStatusCell');
'Cells/FileSizeCell', var DownloadReportCell = require('../../Release/DownloadReportCell');
'Cells/QualityCell', var AgeCell = require('../../Release/AgeCell');
'Cells/ApprovalStatusCell', var ProtocolCell = require('../../Release/ProtocolCell');
'Release/DownloadReportCell', var PeersCell = require('../../Release/PeersCell');
'Release/AgeCell',
'Release/ProtocolCell',
'Release/PeersCell'
], function (Marionette, Backgrid, ReleaseTitleCell, FileSizeCell, QualityCell, ApprovalStatusCell, DownloadReportCell, AgeCell, ProtocolCell, PeersCell) {
return Marionette.Layout.extend({ module.exports = Marionette.Layout.extend({
template: 'Episode/Search/ManualLayoutTemplate', template : 'Episode/Search/ManualLayoutTemplate',
regions : {grid : '#episode-release-grid'},
regions: { columns : [{
grid: '#episode-release-grid' name : 'protocol',
}, label : 'Source',
cell : ProtocolCell
columns: }, {
[ name : 'age',
{ label : 'Age',
name : 'protocol', cell : AgeCell
label : 'Source', }, {
cell : ProtocolCell name : 'title',
}, label : 'Title',
{ cell : ReleaseTitleCell
name : 'age', }, {
label : 'Age', name : 'indexer',
cell : AgeCell label : 'Indexer',
}, cell : Backgrid.StringCell
{ }, {
name : 'title', name : 'size',
label : 'Title', label : 'Size',
cell : ReleaseTitleCell cell : FileSizeCell
}, }, {
{ name : 'seeders',
name : 'indexer', label : 'Peers',
label : 'Indexer', cell : PeersCell
cell : Backgrid.StringCell }, {
}, name : 'quality',
{ label : 'Quality',
name : 'size', cell : QualityCell
label : 'Size', }, {
cell : FileSizeCell name : 'rejections',
}, label : '',
{ cell : ApprovalStatusCell,
name : 'seeders', sortable : false
label : 'Peers', }, {
cell : PeersCell name : 'download',
}, label : '',
{ cell : DownloadReportCell,
name : 'quality', sortable : true
label : 'Quality', }],
cell : QualityCell onShow : function(){
}, if(!this.isClosed) {
{ this.grid.show(new Backgrid.Grid({
name : 'rejections', row : Backgrid.Row,
label : '', columns : this.columns,
cell : ApprovalStatusCell, collection : this.collection,
sortable : false className : 'table table-hover'
}, }));
{ }
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'
}));
}
}
});
});

View File

@ -1,10 +1,3 @@
'use strict'; var Marionette = require('marionette');
define( module.exports = Marionette.ItemView.extend({template : 'Episode/Search/NoResultsViewTemplate'});
[
'marionette'
], function (Marionette) {
return Marionette.ItemView.extend({
template: 'Episode/Search/NoResultsViewTemplate'
});
});

View File

@ -1,134 +1,97 @@
'use strict'; var reqres = require('../../reqres');
define( var Marionette = require('marionette');
[ var Backgrid = require('backgrid');
'reqres', var EpisodeFileModel = require('../../Series/EpisodeFileModel');
'marionette', var EpisodeFileCollection = require('../../Series/EpisodeFileCollection');
'backgrid', var FileSizeCell = require('../../Cells/FileSizeCell');
'Series/EpisodeFileModel', var QualityCell = require('../../Cells/QualityCell');
'Series/EpisodeFileCollection', var DeleteEpisodeFileCell = require('../../Cells/DeleteEpisodeFileCell');
'Cells/FileSizeCell', var NoFileView = require('./NoFileView');
'Cells/QualityCell', var LoadingView = require('../../Shared/LoadingView');
'Cells/DeleteEpisodeFileCell',
'Episode/Summary/NoFileView',
'Shared/LoadingView'
], function (reqres,
Marionette,
Backgrid,
EpisodeFileModel,
EpisodeFileCollection,
FileSizeCell,
QualityCell,
DeleteEpisodeFileCell,
NoFileView,
LoadingView) {
return Marionette.Layout.extend({ module.exports = Marionette.Layout.extend({
template: 'Episode/Summary/EpisodeSummaryLayoutTemplate', template : 'Episode/Summary/EpisodeSummaryLayoutTemplate',
regions : {
regions: { overview : '.episode-overview',
overview: '.episode-overview', activity : '.episode-file-info'
activity: '.episode-file-info' },
}, columns : [{
name : 'path',
columns: label : 'Path',
[ cell : 'string',
{ sortable : false
name : 'path', }, {
label : 'Path', name : 'size',
cell : 'string', label : 'Size',
sortable: false cell : FileSizeCell,
}, sortable : false
{ }, {
name : 'size', name : 'quality',
label : 'Size', label : 'Quality',
cell : FileSizeCell, cell : QualityCell,
sortable: false sortable : false,
}, editable : true
{ }, {
name : 'quality', name : 'this',
label : 'Quality', label : '',
cell : QualityCell, cell : DeleteEpisodeFileCell,
sortable: false, sortable : false
editable: true }],
}, templateHelpers : {},
{ initialize : function(options){
name : 'this', if(!this.model.series) {
label : '', this.templateHelpers.series = options.series.toJSON();
cell : DeleteEpisodeFileCell, }
sortable: false },
} onShow : function(){
], if(this.model.get('hasFile')) {
var episodeFileId = this.model.get('episodeFileId');
templateHelpers: {}, if(reqres.hasHandler(reqres.Requests.GetEpisodeFileById)) {
var episodeFile = reqres.request(reqres.Requests.GetEpisodeFileById, episodeFileId);
initialize: function (options) { this.episodeFileCollection = new EpisodeFileCollection(episodeFile, {seriesId : this.model.get('seriesId')});
if (!this.model.series) { this.listenTo(episodeFile, 'destroy', this._episodeFileDeleted);
this.templateHelpers.series = options.series.toJSON(); this._showTable();
} }
}, else {
this.activity.show(new LoadingView());
onShow: function () { var self = this;
if (this.model.get('hasFile')) { var newEpisodeFile = new EpisodeFileModel({id : episodeFileId});
var episodeFileId = this.model.get('episodeFileId'); this.episodeFileCollection = new EpisodeFileCollection(newEpisodeFile, {seriesId : this.model.get('seriesId')});
var promise = newEpisodeFile.fetch();
if (reqres.hasHandler(reqres.Requests.GetEpisodeFileById)) { this.listenTo(newEpisodeFile, 'destroy', this._episodeFileDeleted);
var episodeFile = reqres.request(reqres.Requests.GetEpisodeFileById, episodeFileId); promise.done(function(){
this.episodeFileCollection = new EpisodeFileCollection(episodeFile, { seriesId: this.model.get('seriesId') }); self._showTable();
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
}); });
} }
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
}); });
}); }
});

View File

@ -1,11 +1,3 @@
'use strict'; var Marionette = require('marionette');
define(
[
'marionette'
], function (Marionette) {
return Marionette.ItemView.extend({ module.exports = Marionette.ItemView.extend({template : 'Episode/Summary/NoFileViewTemplate'});
template: 'Episode/Summary/NoFileViewTemplate'
});
});

Some files were not shown because too many files have changed in this diff Show More