mirror of
https://github.com/Readarr/Readarr.git
synced 2026-04-25 22:36:59 -04:00
Merge branch 'quality-definitions' into develop
Conflicts: src/UI/Settings/Quality/Profile/EditQualityProfileTemplate.html src/UI/app.js
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
<fieldset>
|
||||
<legend>Quality Definitions</legend>
|
||||
<div class="span11">
|
||||
<div id="quality-definition-list">
|
||||
<div class="quality-header x-header">
|
||||
<div class="row">
|
||||
<span class="span2">Quality</span>
|
||||
<span class="span2">Title</span>
|
||||
<span class="offset1 span4">Size Limit</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rows x-rows">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
define(
|
||||
[
|
||||
'marionette',
|
||||
'backgrid',
|
||||
'Settings/Quality/Definition/QualityDefinitionView'
|
||||
], function (Marionette, Backgrid, QualityDefinitionView) {
|
||||
|
||||
return Marionette.CompositeView.extend({
|
||||
template: 'Settings/Quality/Definition/QualityDefinitionCollectionTemplate',
|
||||
|
||||
itemViewContainer: ".x-rows",
|
||||
|
||||
itemView: QualityDefinitionView
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
<span class="span2">
|
||||
{{quality.name}}
|
||||
</span>
|
||||
<span class="span2">
|
||||
<input type="text" class="x-title input-block-level" value="{{title}}">
|
||||
</span>
|
||||
<span class="offset1 span4">
|
||||
<div class="x-slider"></div>
|
||||
<div class="size-label-wrapper">
|
||||
<div class="pull-left">
|
||||
<span class="label label-warning x-min-thirty"
|
||||
name="thirtyMinuteMinSize"
|
||||
title="Minimum size for a 30 minute episode">
|
||||
</span>
|
||||
<span class="label label-info x-min-sixty"
|
||||
name="sixtyMinuteMinSize"
|
||||
title="Minimum size for a 60 minute episode">
|
||||
</span>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<span class="label label-warning x-max-thirty"
|
||||
name="thirtyMinuteMaxSize"
|
||||
title="Maximum size for a 30 minute episode">
|
||||
</span>
|
||||
<span class="label label-info x-max-sixty"
|
||||
name="sixtyMinuteMaxSize"
|
||||
title="Maximum size for a 60 minute episode">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
@@ -0,0 +1,86 @@
|
||||
'use strict';
|
||||
|
||||
define(
|
||||
[
|
||||
'marionette',
|
||||
'Mixins/AsModelBoundView',
|
||||
'filesize',
|
||||
'jquery-ui'
|
||||
], function (Marionette, AsModelBoundView, fileSize) {
|
||||
|
||||
var view = Marionette.ItemView.extend({
|
||||
template: 'Settings/Quality/Definition/QualityDefinitionTemplate',
|
||||
className: 'row',
|
||||
|
||||
ui: {
|
||||
title : '.x-title',
|
||||
sizeSlider : '.x-slider',
|
||||
thirtyMinuteMinSize: '.x-min-thirty',
|
||||
sixtyMinuteMinSize : '.x-min-sixty',
|
||||
thirtyMinuteMaxSize: '.x-max-thirty',
|
||||
sixtyMinuteMaxSize : '.x-max-sixty'
|
||||
},
|
||||
|
||||
events: {
|
||||
'change .x-title': '_updateTitle',
|
||||
'slide .x-slider': '_updateSize'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
this.qualityProfileCollection = options.qualityProfiles;
|
||||
this.filesize = fileSize;
|
||||
},
|
||||
|
||||
onRender: function () {
|
||||
this.ui.sizeSlider.slider({
|
||||
range : true,
|
||||
min : 0,
|
||||
max : 200,
|
||||
values : [ this.model.get('minSize'), this.model.get('maxSize') ],
|
||||
});
|
||||
|
||||
this._changeSize();
|
||||
},
|
||||
|
||||
_updateTitle: function() {
|
||||
this.model.set('title', this.ui.title.val());
|
||||
},
|
||||
|
||||
_updateSize: function (event, ui) {
|
||||
this.model.set('minSize', ui.values[0]);
|
||||
this.model.set('maxSize', ui.values[1]);
|
||||
|
||||
this._changeSize();
|
||||
},
|
||||
|
||||
_changeSize: function () {
|
||||
var minSize = this.model.get('minSize');
|
||||
var maxSize = this.model.get('maxSize');
|
||||
|
||||
{
|
||||
var minBytes = minSize * 1024 * 1024;
|
||||
var minThirty = fileSize(minBytes * 30, 1, false);
|
||||
var minSixty = fileSize(minBytes * 60, 1, false);
|
||||
|
||||
this.ui.thirtyMinuteMinSize.html(minThirty);
|
||||
this.ui.sixtyMinuteMinSize.html(minSixty);
|
||||
}
|
||||
|
||||
{
|
||||
var maxBytes = maxSize * 1024 * 1024;
|
||||
var maxThirty = fileSize(maxBytes * 30, 1, false);
|
||||
var maxSixty = fileSize(maxBytes * 60, 1, false);
|
||||
|
||||
this.ui.thirtyMinuteMaxSize.html(maxThirty);
|
||||
this.ui.sixtyMinuteMaxSize.html(maxSixty);
|
||||
}
|
||||
|
||||
/*if (parseInt(maxSize, 10) === 0) {
|
||||
thirty = 'No Limit';
|
||||
sixty = 'No Limit';
|
||||
}*/
|
||||
}
|
||||
});
|
||||
|
||||
return AsModelBoundView.call(view);
|
||||
});
|
||||
@@ -7,13 +7,14 @@ define(
|
||||
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> ';
|
||||
_.each(this.items, function (item) {
|
||||
if (item.allowed) {
|
||||
if (item.quality.id === cutoff.id) {
|
||||
ret += '<span class="label label-info" title="Cutoff">' + item.quality.name + '</span> ';
|
||||
}
|
||||
else {
|
||||
ret += '<span class="label">' + item.quality.name + '</span> ';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'marionette'
|
||||
], function (Marionette) {
|
||||
return Marionette.ItemView.extend({
|
||||
template : 'Settings/Quality/Profile/Edit/EditQualityProfileItemViewTemplate'
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
<i class="select-handle pull-left x-select" />
|
||||
<span class="quality-label">{{quality.name}}</span>
|
||||
<i class="drag-handle pull-right icon-reorder advanced-setting x-drag-handle" />
|
||||
@@ -0,0 +1,108 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'underscore',
|
||||
'vent',
|
||||
'marionette',
|
||||
'backbone',
|
||||
'Settings/Quality/Profile/Edit/EditQualityProfileItemView',
|
||||
'Settings/Quality/Profile/Edit/QualitySortableCollectionView',
|
||||
'Settings/Quality/Profile/Edit/EditQualityProfileView',
|
||||
'Config'
|
||||
], function (_, vent, Marionette, Backbone, EditQualityProfileItemView, QualitySortableCollectionView, EditQualityProfileView, Config) {
|
||||
|
||||
return Marionette.Layout.extend({
|
||||
template: 'Settings/Quality/Profile/Edit/EditQualityProfileLayoutTemplate',
|
||||
|
||||
regions: {
|
||||
fields : '#x-fields',
|
||||
qualities: '#x-qualities'
|
||||
},
|
||||
|
||||
events: {
|
||||
'click .x-save' : '_saveQualityProfile',
|
||||
'click .x-cancel': '_cancelQualityProfile'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
this.profileCollection = options.profileCollection;
|
||||
this.itemsCollection = new Backbone.Collection(_.toArray(this.model.get('items')).reverse());
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
this.fieldsView = new EditQualityProfileView({ model: this.model });
|
||||
this._showFieldsView();
|
||||
|
||||
this.sortableListView = new QualitySortableCollectionView({
|
||||
selectable : true,
|
||||
selectMultiple : true,
|
||||
clickToSelect : true,
|
||||
clickToToggle : true,
|
||||
sortable : Config.getValueBoolean(Config.Keys.AdvancedSettings, false),
|
||||
|
||||
sortableOptions : {
|
||||
handle: '.x-drag-handle'
|
||||
},
|
||||
|
||||
collection: this.itemsCollection,
|
||||
model : this.model
|
||||
});
|
||||
|
||||
this.sortableListView.setSelectedModels(this.itemsCollection.filter(function(item) { return item.get('allowed') === true; }));
|
||||
this.qualities.show(this.sortableListView);
|
||||
|
||||
this.listenTo(this.sortableListView, 'selectionChanged', this._selectionChanged);
|
||||
this.listenTo(this.sortableListView, 'sortStop', this._updateModel);
|
||||
},
|
||||
|
||||
_selectionChanged: function(newSelectedModels, oldSelectedModels) {
|
||||
var addedModels = _.difference(newSelectedModels, oldSelectedModels);
|
||||
var removeModels = _.difference(oldSelectedModels, newSelectedModels);
|
||||
|
||||
_.each(removeModels, function(item) { item.set('allowed', false); });
|
||||
_.each(addedModels, function(item) { item.set('allowed', true); });
|
||||
|
||||
this._updateModel();
|
||||
},
|
||||
|
||||
_updateModel: function() {
|
||||
this.model.set('items', this.itemsCollection.toJSON().reverse());
|
||||
|
||||
this._showFieldsView();
|
||||
},
|
||||
|
||||
_saveQualityProfile: function () {
|
||||
var self = this;
|
||||
var cutoff = this.fieldsView.getCutoff();
|
||||
this.model.set('cutoff', cutoff);
|
||||
|
||||
var promise = this.model.save();
|
||||
|
||||
if (promise) {
|
||||
promise.done(function () {
|
||||
self.profileCollection.add(self.model, { merge: true });
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_cancelQualityProfile: function () {
|
||||
if (!this.model.has('id')) {
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
return;
|
||||
}
|
||||
|
||||
var promise = this.model.fetch();
|
||||
|
||||
if (promise) {
|
||||
promise.done(function () {
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_showFieldsView: function () {
|
||||
this.fields.show(this.fieldsView);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close x-cancel" aria-hidden="true">×</button>
|
||||
{{#if id}}
|
||||
<h3>Edit</h3>
|
||||
{{else}}
|
||||
<h3>Add</h3>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-horizontal">
|
||||
<div id="x-fields"></div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">Qualities</label>
|
||||
<div class="controls qualities-controls">
|
||||
<span id="x-qualities"></span>
|
||||
<span class="help-inline">
|
||||
<i class="icon-question-sign" title="Qualities higher in the list are more preferred. Only checked qualities will be wanted."/>
|
||||
</span>
|
||||
</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 x-cancel">cancel</button>
|
||||
<button class="btn btn-primary x-save">save</button>
|
||||
</div>
|
||||
@@ -0,0 +1,26 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'underscore',
|
||||
'marionette',
|
||||
'Mixins/AsModelBoundView',
|
||||
'Mixins/AsValidatedView'
|
||||
], function (_, Marionette, AsModelBoundView, AsValidatedView) {
|
||||
|
||||
var view = Marionette.ItemView.extend({
|
||||
template: 'Settings/Quality/Profile/Edit/EditQualityProfileViewTemplate',
|
||||
|
||||
ui: {
|
||||
cutoff : '.x-cutoff'
|
||||
},
|
||||
|
||||
getCutoff: function () {
|
||||
var self = this;
|
||||
|
||||
return _.findWhere(_.pluck(this.model.get('items'), 'quality'), { id: parseInt(self.ui.cutoff.val(), 10)});
|
||||
}
|
||||
});
|
||||
|
||||
AsValidatedView.call(view);
|
||||
return AsModelBoundView.call(view);
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
<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">
|
||||
{{#eachReverse items}}
|
||||
{{#if allowed}}
|
||||
<option value="{{quality.id}}">{{quality.name}}</option>
|
||||
{{/if}}
|
||||
{{/eachReverse}}
|
||||
</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>
|
||||
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'backbone.collectionview',
|
||||
'Settings/Quality/Profile/Edit/EditQualityProfileItemView'
|
||||
], function (BackboneSortableCollectionView, EditQualityProfileItemView) {
|
||||
return BackboneSortableCollectionView.extend({
|
||||
|
||||
className: 'qualities',
|
||||
modelView: EditQualityProfileItemView,
|
||||
|
||||
attributes: {
|
||||
'validation-name': 'items'
|
||||
},
|
||||
|
||||
events: {
|
||||
'click li, td' : '_listItem_onMousedown',
|
||||
'dblclick li, td' : '_listItem_onDoubleClick',
|
||||
'keydown' : '_onKeydown'
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,60 +0,0 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</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-nd-form-info" 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>
|
||||
@@ -1,83 +0,0 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'vent',
|
||||
'marionette',
|
||||
'backbone',
|
||||
'Mixins/AsModelBoundView',
|
||||
'Mixins/AsValidatedView',
|
||||
'underscore'
|
||||
], function (vent, Marionette, Backbone, 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(), 10)});
|
||||
this.model.set('cutoff', cutoff);
|
||||
|
||||
var promise = this.model.save();
|
||||
|
||||
if (promise) {
|
||||
promise.done(function () {
|
||||
self.profileCollection.add(self.model, { merge: true });
|
||||
vent.trigger(vent.Commands.CloseModalCommand);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
AsValidatedView.call(view);
|
||||
return AsModelBoundView.call(view);
|
||||
|
||||
});
|
||||
@@ -3,7 +3,7 @@
|
||||
define(['AppLayout',
|
||||
'marionette',
|
||||
'Settings/Quality/Profile/QualityProfileView',
|
||||
'Settings/Quality/Profile/EditQualityProfileView',
|
||||
'Settings/Quality/Profile/Edit/EditQualityProfileLayout',
|
||||
'Settings/Quality/Profile/QualityProfileSchemaCollection',
|
||||
'underscore'
|
||||
], function (AppLayout, Marionette, QualityProfileView, EditProfileView, ProfileCollection, _) {
|
||||
|
||||
@@ -4,7 +4,7 @@ define(
|
||||
[
|
||||
'AppLayout',
|
||||
'marionette',
|
||||
'Settings/Quality/Profile/EditQualityProfileView',
|
||||
'Settings/Quality/Profile/Edit/EditQualityProfileLayout',
|
||||
'Settings/Quality/Profile/DeleteView',
|
||||
'Series/SeriesCollection',
|
||||
'Mixins/AsModelBoundView',
|
||||
@@ -13,7 +13,7 @@ define(
|
||||
], function (AppLayout, Marionette, EditProfileView, DeleteProfileView, SeriesCollection, AsModelBoundView) {
|
||||
|
||||
var view = Marionette.ItemView.extend({
|
||||
template: 'Settings/Quality/Profile/QualityProfileTemplate',
|
||||
template: 'Settings/Quality/Profile/QualityProfileViewTemplate',
|
||||
tagName : 'li',
|
||||
|
||||
ui: {
|
||||
|
||||
@@ -5,27 +5,27 @@ define(
|
||||
'marionette',
|
||||
'Quality/QualityProfileCollection',
|
||||
'Settings/Quality/Profile/QualityProfileCollectionView',
|
||||
'Quality/QualitySizeCollection',
|
||||
'Settings/Quality/Size/QualitySizeCollectionView'
|
||||
], function (Marionette, QualityProfileCollection, QualityProfileCollectionView, QualitySizeCollection, QualitySizeCollectionView) {
|
||||
'Quality/QualityDefinitionCollection',
|
||||
'Settings/Quality/Definition/QualityDefinitionCollectionView'
|
||||
], function (Marionette, QualityProfileCollection, QualityProfileCollectionView, QualityDefinitionCollection, QualityDefinitionCollectionView) {
|
||||
return Marionette.Layout.extend({
|
||||
template: 'Settings/Quality/QualityLayoutTemplate',
|
||||
|
||||
regions: {
|
||||
qualityProfile : '#quality-profile',
|
||||
qualitySize : '#quality-size'
|
||||
qualityProfile : '#quality-profile',
|
||||
qualityDefinition : '#quality-definition'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
this.settings = options.settings;
|
||||
QualityProfileCollection.fetch();
|
||||
this.qualitySizeCollection = new QualitySizeCollection();
|
||||
this.qualitySizeCollection.fetch();
|
||||
this.qualityDefinitionCollection = new QualityDefinitionCollection();
|
||||
this.qualityDefinitionCollection.fetch();
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
this.qualityProfile.show(new QualityProfileCollectionView({collection: QualityProfileCollection}));
|
||||
this.qualitySize.show(new QualitySizeCollectionView({collection: this.qualitySizeCollection}));
|
||||
this.qualityDefinition.show(new QualityDefinitionCollectionView({collection: this.qualityDefinitionCollection}));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
<br/>
|
||||
|
||||
<div class="row advanced-setting">
|
||||
<div class="span12" id="quality-size"/>
|
||||
<div class="span12" id="quality-definition"/>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<fieldset>
|
||||
<legend>Quality Size Limits</legend>
|
||||
<ul class="quality-sizes"/>
|
||||
</fieldset>
|
||||
@@ -1,9 +0,0 @@
|
||||
'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'
|
||||
});
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
<div class="quality-size-item">
|
||||
<h3 class="center-block">{{name}}</h3>
|
||||
<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>
|
||||
@@ -1,61 +0,0 @@
|
||||
'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, 10) === 0) {
|
||||
thirty = 'No Limit';
|
||||
sixty = 'No Limit';
|
||||
}
|
||||
|
||||
this.ui.thirtyMinuteSize.html(thirty);
|
||||
this.ui.sixtyMinuteSize.html(sixty);
|
||||
}
|
||||
});
|
||||
|
||||
return AsModelBoundView.call(view);
|
||||
});
|
||||
@@ -1,6 +1,8 @@
|
||||
@import "../../Shared/Styles/card";
|
||||
@import "../../Content/Bootstrap/mixins";
|
||||
@import "../../Content/FontAwesome/font-awesome";
|
||||
|
||||
.quality-profiles, .quality-sizes {
|
||||
.quality-profiles {
|
||||
li {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
@@ -35,41 +37,130 @@
|
||||
}
|
||||
}
|
||||
|
||||
.quality-size-item {
|
||||
ul.qualities {
|
||||
.user-select(none);
|
||||
|
||||
.card;
|
||||
text-align: center;
|
||||
min-height: 100px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
outline: none;
|
||||
width: 220px;
|
||||
display: inline-block;
|
||||
|
||||
li {
|
||||
margin: 2px;
|
||||
padding: 2px 4px;
|
||||
line-height: 20px;
|
||||
border: 1px solid #aaaaaa;
|
||||
border-radius: 4px; /* may need vendor varients */
|
||||
background: #fafafa;
|
||||
cursor: pointer;
|
||||
|
||||
width: 200px;
|
||||
height: 210px;
|
||||
padding: 10px 15px;
|
||||
&.selected {
|
||||
.select-handle {
|
||||
opacity: 1.0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 0px;
|
||||
}
|
||||
.quality-label {
|
||||
color: #444444;
|
||||
}
|
||||
|
||||
.size {
|
||||
position: relative;
|
||||
height: 100px;
|
||||
margin: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
.select-handle:before {
|
||||
.icon(@check);
|
||||
}
|
||||
}
|
||||
|
||||
.knob {
|
||||
box-shadow: none;
|
||||
}
|
||||
&:hover {
|
||||
border-color: #888888;
|
||||
background: #eeeeee;
|
||||
|
||||
.size-value-wrapper {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
width: 100%;
|
||||
.drag-handle {
|
||||
opacity: 1.0;
|
||||
cursor: move;
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
margin-top: 2px;
|
||||
.quality-label {
|
||||
color: #c6c6c6;
|
||||
}
|
||||
.drag-handle, .select-handle {
|
||||
opacity: 0.2;
|
||||
line-height: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select-handle:before {
|
||||
.icon(@check-empty);
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#quality-size {
|
||||
overflow: hidden;
|
||||
.qualities-controls {
|
||||
.help-inline {
|
||||
vertical-align: top;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
#quality-definition-list {
|
||||
|
||||
.quality-header .row {
|
||||
font-weight: bold;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.rows .row {
|
||||
line-height: 30px;
|
||||
border-top: 1px solid #ddd;
|
||||
vertical-align: middle;
|
||||
padding: 5px;
|
||||
|
||||
input {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.size-label-wrapper {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.label {
|
||||
min-width: 70px;
|
||||
text-align: center;
|
||||
margin: 0px 1px;
|
||||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
.ui-slider {
|
||||
position: relative;
|
||||
text-align: left;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #ccc;
|
||||
height: 8px;
|
||||
|
||||
.ui-slider-range {
|
||||
position: absolute;
|
||||
display: block;
|
||||
background-color: #ddd;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ui-slider-handle {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
width: 6px;
|
||||
height: 12px;
|
||||
cursor: default;
|
||||
background-color: #ccc;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 3px;
|
||||
top: -3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'vent',
|
||||
'marionette',
|
||||
'backbone',
|
||||
@@ -17,7 +18,8 @@ define(
|
||||
'Settings/General/GeneralView',
|
||||
'Shared/LoadingView',
|
||||
'Config'
|
||||
], function (vent,
|
||||
], function ($,
|
||||
vent,
|
||||
Marionette,
|
||||
Backbone,
|
||||
SettingsModel,
|
||||
@@ -192,24 +194,24 @@ define(
|
||||
},
|
||||
|
||||
_setAdvancedSettingsState: function () {
|
||||
var checked = Config.getValueBoolean('advancedSettings');
|
||||
var checked = Config.getValueBoolean(Config.Keys.AdvancedSettings);
|
||||
this.ui.advancedSettings.prop('checked', checked);
|
||||
|
||||
if (checked) {
|
||||
this.$el.addClass('show-advanced-settings');
|
||||
$('body').addClass('show-advanced-settings');
|
||||
}
|
||||
},
|
||||
|
||||
_toggleAdvancedSettings: function () {
|
||||
var checked = this.ui.advancedSettings.prop('checked');
|
||||
Config.setValue('advancedSettings', checked);
|
||||
Config.setValue(Config.Keys.AdvancedSettings, checked);
|
||||
|
||||
if (checked) {
|
||||
this.$el.addClass('show-advanced-settings');
|
||||
$('body').addClass('show-advanced-settings');
|
||||
}
|
||||
|
||||
else {
|
||||
this.$el.removeClass('show-advanced-settings');
|
||||
$('body').removeClass('show-advanced-settings');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user