Moved source code under src folder - massive change

This commit is contained in:
Mark McDowall
2013-10-02 18:01:32 -07:00
parent 2fc8123d6b
commit 5bf0e197ec
1499 changed files with 1054 additions and 1444 deletions
@@ -0,0 +1,18 @@
'use strict';
define(['app', 'handlebars'], function (App,Handlebars) {
Handlebars.registerHelper('allowedLabeler', function () {
var ret = '';
var cutoff = this.cutoff;
_.each(this.allowed, function (allowed) {
if (allowed.id === cutoff.id) {
ret += '<span class="label label-info" title="Cutoff">' + allowed.name + '</span> ';
}
else {
ret += '<span class="label">' + allowed.name + '</span> ';
}
});
return new Handlebars.SafeString(ret);
});
});
@@ -0,0 +1,11 @@
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>Delete: {{name}}</h3>
</div>
<div class="modal-body">
<p>Are you sure you want to delete '{{name}}'?</p>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal">cancel</button>
<button class="btn btn-danger x-confirm-delete">delete</button>
</div>
@@ -0,0 +1,24 @@
'use strict';
define(
[
'app',
'marionette'
], function (App, Marionette) {
return Marionette.ItemView.extend({
template: 'Settings/Quality/Profile/DeleteTemplate',
events: {
'click .x-confirm-delete': '_removeProfile'
},
_removeProfile: function () {
this.model.destroy({
wait: true
}).done(function () {
App.vent.trigger(App.Commands.CloseModalCommand);
});
}
});
});
@@ -0,0 +1,60 @@
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
{{#if id}}
<h3>Edit</h3>
{{else}}
<h3>Add</h3>
{{/if}}
</div>
<div class="modal-body">
<div class="form-horizontal">
<div class="control-group">
<label class="control-label">Name</label>
<div class="controls">
<input type="text" name="name">
</div>
</div>
<div class="control-group">
<label class="control-label">Cutoff</label>
<div class="controls">
<select class="x-cutoff" name="cutoff.id" validation-name="cutoff">
{{#each allowed}}
<option value="{{id}}">{{name}}</option>
{{/each}}
</select>
<span class="help-inline">
<i class="icon-question-sign" title="Once this quality is reached NzbDrone will no longer download episodes"/>
</span>
</div>
</div>
</div>
<div>
<div class="offset1 span3">
<h3>Available</h3>
<select multiple="multiple" class="x-available-list">
{{#each available}}
<option value="{{id}}">{{name}}</option>
{{/each}}
</select>
</div>
<div class="span3">
<div class="control-group">
<div class="controls">
<h3>Allowed</h3>
<select multiple="multiple" class="x-allowed-list" validation-name="allowed">
{{#each allowed}}
<option value="{{id}}">{{name}}</option>
{{/each}}
</select>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
{{#if id}}
<button class="btn btn-danger pull-left x-delete">delete</button>
{{/if}}
<button class="btn" data-dismiss="modal">cancel</button>
<button class="btn btn-primary x-save">save</button>
</div>
@@ -0,0 +1,81 @@
'use strict';
define(
[
'app',
'marionette',
'Mixins/AsModelBoundView',
'Mixins/AsValidatedView'
], function (App, Marionette, AsModelBoundView, AsValidatedView) {
var view = Marionette.ItemView.extend({
template: 'Settings/Quality/Profile/EditQualityProfileTemplate',
ui: {
cutoff: '.x-cutoff'
},
events: {
'click .x-save' : '_saveQualityProfile',
'dblclick .x-available-list': '_moveQuality',
'dblclick .x-allowed-list' : '_moveQuality'
},
initialize: function (options) {
this.profileCollection = options.profileCollection;
},
_moveQuality: function (event) {
var quality;
var qualityId = event.target.value;
var availableCollection = new Backbone.Collection(this.model.get('available'));
availableCollection.comparator = function (model) {
return model.get('weight');
};
var allowedCollection = new Backbone.Collection(this.model.get('allowed'));
allowedCollection.comparator = function (model) {
return model.get('weight');
};
if (availableCollection.get(qualityId)) {
quality = availableCollection.get(qualityId);
availableCollection.remove(quality);
allowedCollection.add(quality);
}
else if (allowedCollection.get(qualityId)) {
quality = allowedCollection.get(qualityId);
allowedCollection.remove(quality);
availableCollection.add(quality);
}
else {
throw 'couldnt find quality id ' + qualityId;
}
this.model.set('available', availableCollection.toJSON());
this.model.set('allowed', allowedCollection.toJSON());
this.render();
},
_saveQualityProfile: function () {
var self = this;
var cutoff = _.findWhere(this.model.get('allowed'), { id: parseInt(this.ui.cutoff.val())});
this.model.set('cutoff', cutoff);
var promise = this.model.save();
if (promise) {
promise.done(function () {
self.profileCollection.add(self.model, { merge: true });
App.vent.trigger(App.Commands.CloseModalCommand);
});
}
}
});
AsValidatedView.call(view);
return AsModelBoundView.call(view);
});
@@ -0,0 +1,16 @@
<fieldset>
<legend>Quality Profiles</legend>
<div class="row">
<div class="span12">
<ul class="quality-profiles">
<li>
<div class="quality-profile-item add-card x-add-card">
<span class="center well">
<i class="icon-plus" title="Add Profile"/>
</span>
</div>
</li>
</ul>
</div>
</div>
</fieldset>
@@ -0,0 +1,43 @@
'use strict';
define(['app',
'marionette',
'Settings/Quality/Profile/QualityProfileView',
'Settings/Quality/Profile/EditQualityProfileView',
'Settings/Quality/Profile/QualityProfileSchemaCollection'
], function (App, Marionette, QualityProfileView, EditProfileView, ProfileCollection) {
return Marionette.CompositeView.extend({
itemView : QualityProfileView,
itemViewContainer: '.quality-profiles',
template : 'Settings/Quality/Profile/QualityProfileCollectionTemplate',
ui: {
'addCard': '.x-add-card'
},
events: {
'click .x-add-card': '_addProfile'
},
appendHtml: function(collectionView, itemView, index){
collectionView.ui.addCard.parent('li').before(itemView.el);
},
_addProfile: function () {
var self = this;
var schemaCollection = new ProfileCollection();
schemaCollection.fetch({
success: function (collection) {
var model = _.first(collection.models);
model.set('id', undefined);
model.set('name', '');
model.collection = self.collection;
var view = new EditProfileView({ model: model, profileCollection: self.collection});
App.modalRegion.show(view);
}
});
}
});
});
@@ -0,0 +1,13 @@
"use strict";
define(
[
'backbone',
'Quality/QualityProfileModel'
], function (Backbone, QualityProfileModel) {
return Backbone.Collection.extend({
model: QualityProfileModel,
url : window.NzbDrone.ApiRoot + '/qualityprofiles/schema'
});
});
@@ -0,0 +1,11 @@
<div class="quality-profile-item">
<div>
<h3 name="name"></h3>
<span class="btn-group pull-right">
<button class="btn btn-mini btn-icon-only x-edit"><i class="icon-nd-edit"/></button>
<button class="btn btn-mini btn-icon-only x-delete"><i class="icon-nd-delete"/></button>
</span>
</div>
{{allowedLabeler}}
</div>
@@ -0,0 +1,71 @@
'use strict';
define(
[
'app',
'marionette',
'Settings/Quality/Profile/EditQualityProfileView',
'Settings/Quality/Profile/DeleteView',
'Series/SeriesCollection',
'Mixins/AsModelBoundView',
'Settings/Quality/Profile/AllowedLabeler',
'bootstrap',
], function (App, Marionette, EditProfileView, DeleteProfileView, SeriesCollection, AsModelBoundView) {
var view = Marionette.ItemView.extend({
template: 'Settings/Quality/Profile/QualityProfileTemplate',
tagName : 'li',
ui: {
'progressbar' : '.progress .bar',
'deleteButton': '.x-delete'
},
events: {
'click .x-edit' : '_editProfile',
'click .x-delete': '_deleteProfile'
},
initialize: function () {
this.listenTo(this.model, 'sync', this.render);
this.listenTo(SeriesCollection, 'all', this._updateDisableStatus)
},
_editProfile: function () {
var view = new EditProfileView({ model: this.model, profileCollection: this.model.collection });
App.modalRegion.show(view);
},
_deleteProfile: function () {
if (this._isQualityInUse()) {
return;
}
var view = new DeleteProfileView({ model: this.model });
App.modalRegion.show(view);
},
onRender: function () {
this._updateDisableStatus();
},
_updateDisableStatus: function () {
if (this._isQualityInUse()) {
this.ui.deleteButton.addClass('disabled');
this.ui.deleteButton.attr('title', 'Can\'t delete quality profiles attached to a series.');
}
else {
this.ui.deleteButton.removeClass('disabled');
this.ui.deleteButton.attr('title', 'Delete Quality Profile');
}
},
_isQualityInUse: function () {
return SeriesCollection.where({'qualityProfileId': this.model.id}).length !== 0;
}
});
return AsModelBoundView.call(view);
});
+32
View File
@@ -0,0 +1,32 @@
"use strict";
define(
[
'marionette',
'Quality/QualityProfileCollection',
'Settings/Quality/Profile/QualityProfileCollectionView',
'Quality/QualitySizeCollection',
'Settings/Quality/Size/QualitySizeCollectionView'
], function (Marionette, QualityProfileCollection, QualityProfileCollectionView, QualitySizeCollection, QualitySizeCollectionView) {
return Marionette.Layout.extend({
template: 'Settings/Quality/QualityLayoutTemplate',
regions: {
qualityProfile : '#quality-profile',
qualitySize : '#quality-size'
},
initialize: function (options) {
this.settings = options.settings;
QualityProfileCollection.fetch();
this.qualitySizeCollection = new QualitySizeCollection();
this.qualitySizeCollection.fetch();
},
onShow: function () {
this.qualityProfile.show(new QualityProfileCollectionView({collection: QualityProfileCollection}));
this.qualitySize.show(new QualitySizeCollectionView({collection: this.qualitySizeCollection}));
}
});
});
@@ -0,0 +1,6 @@
<div class="row">
<div class="span12" id="quality-profile"/>
</div>
<!--<div class="row">
<div class="span12" id="quality-size"/>
</div>-->
@@ -0,0 +1,4 @@
<fieldset>
<legend>Quality Size Limits</legend>
<ul class="quality-sizes"/>
</fieldset>
@@ -0,0 +1,9 @@
'use strict';
define(['marionette', 'Settings/Quality/Size/QualitySizeView'], function (Marionette, QualitySizeView) {
return Marionette.CompositeView.extend({
itemView : QualitySizeView,
itemViewContainer: '.quality-sizes',
template : 'Settings/Quality/Size/QualitySizeCollectionTemplate'
});
});
@@ -0,0 +1,20 @@
<div class="quality-size-item">
<h2 class="center-block">{{name}}</h2>
<div class="size">
<div class="size-value-wrapper">
<div>
<span class="label label-large label-warning x-size-thirty"
name="thirtyMinuteSize"
title="Maximum size for a 30 minute episode">
</span>
</div>
<div>
<span class="label label-large label-info x-size-sixty"
name="sixtyMinuteSize"
title="Maximum size for a 60 minute episode">
</span>
</div>
</div>
<input type="text" name="maxSize" class="knob x-knob" />
</div>
</div>
@@ -0,0 +1,55 @@
'use strict';
define(['marionette', 'Mixins/AsModelBoundView', 'filesize', 'jquery.knob' ], function (Marionette, AsModelBoundView, Filesize) {
var view = Marionette.ItemView.extend({
template : 'Settings/Quality/Size/QualitySizeTemplate',
tagName : 'li',
ui: {
knob : '.x-knob',
thirtyMinuteSize: '.x-size-thirty',
sixtyMinuteSize : '.x-size-sixty'
},
events: {
'change .x-knob': '_changeMaxSize'
},
initialize: function (options) {
this.qualityProfileCollection = options.qualityProfiles;
this.filesize = Filesize;
},
onRender: function () {
this.ui.knob.knob({
min : 0,
max : 200,
step : 1,
cursor : 25,
width : 150,
stopper : true,
displayInput : false
});
this._changeMaxSize();
},
_changeMaxSize: function () {
var maxSize = this.model.get('maxSize');
var bytes = maxSize * 1024 * 1024;
var thirty = Filesize(bytes * 30, 1, false);
var sixty = Filesize(bytes * 60, 1, false);
if (parseInt(maxSize) === 0) {
thirty = 'No Limit';
sixty = 'No Limit';
}
this.ui.thirtyMinuteSize.html(thirty);
this.ui.sixtyMinuteSize.html(sixty);
}
});
return AsModelBoundView.call(view);
});
+75
View File
@@ -0,0 +1,75 @@
@import "../../Shared/Styles/card";
.quality-profiles, .quality-sizes {
li {
display: inline-block;
vertical-align: top;
}
}
.quality-profile-item {
.card;
width: 300px;
height: 120px;
padding: 10px 15px;
h3 {
margin-top: 0px;
display: inline-block;
width: 240px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.btn-group {
margin-top: 8px;
}
&.add-card {
.center {
margin-top: 30px;
}
}
}
.quality-size-item {
.card;
text-align: center;
width: 200px;
height: 220px;
padding: 10px 15px;
h3 {
margin-top: 0px;
}
.size {
position: relative;
height: 100px;
margin: 10px;
text-align: center;
}
.knob {
box-shadow: none;
}
.size-value-wrapper {
position: absolute;
top: 50px;
width: 100%;
div {
margin-top: 2px;
}
}
}
#quality-size {
overflow: hidden;
}