diff --git a/couchpotato/core/plugins/profile/static/handle.png b/couchpotato/core/plugins/profile/static/handle.png
new file mode 100644
index 0000000..adff5b2
Binary files /dev/null and b/couchpotato/core/plugins/profile/static/handle.png differ
diff --git a/couchpotato/core/plugins/profile/static/profile.css b/couchpotato/core/plugins/profile/static/profile.css
index ab6ef98..8975237 100644
--- a/couchpotato/core/plugins/profile/static/profile.css
+++ b/couchpotato/core/plugins/profile/static/profile.css
@@ -1,18 +1,84 @@
-.profile > .delete {
- background-position: center;
- height: 20px;
- width: 20px;
-}
+/* @override http://192.168.1.20:5000/static/profile_plugin/profile.css */
-.profile .types .type .handle {
- background: url('../../images/handle.png') center;
- display: inline-block;
- height: 20px;
- width: 20px;
+.add_new_profile {
+ padding: 20px;
+ display: block;
+ text-align: center;
+ font-size: 20px;
+ border-bottom: 1px solid rgba(255,255,255,0.2);
}
-.profile .types .type .delete {
- background-position: center;
- height: 20px;
- width: 20px;
-}
\ No newline at end of file
+.profile { border-bottom: 1px solid rgba(255,255,255,0.2) }
+
+ .profile > .delete {
+ height: 20px;
+ width: 20px;
+ position: absolute;
+ margin-left: 690px;
+ padding: 14px;
+ background-position: center;
+ }
+
+ .profile .formHint {
+ width: 250px !important;
+ }
+
+ .profile .wait_for {
+ position: absolute;
+ margin: -45px 0 0 437px;
+ }
+
+ .profile .wait_for input {
+ margin: 0 5px !important;
+ }
+
+ .profile .types {
+ padding: 0;
+ margin: 0 20px 0 -4px;
+ display: inline-block;
+ }
+
+ .profile .types li {
+ padding: 3px 5px;
+ border-bottom: 1px solid rgba(255,255,255,0.2);
+ }
+ .profile .types li:last-child { border: 0; }
+
+ .profile .types li > * {
+ display: inline-block;
+ vertical-align: middle;
+ line-height: 0;
+ margin-right: 10px;
+ }
+
+ .profile .quality_type select {
+ width: 186px;
+ margin-left: -1px;
+ }
+
+ .profile .types li.is_empty .check, .profile .types li.is_empty .delete, .profile .types li.is_empty .handle {
+ visibility: hidden;
+ }
+
+ .profile .types .type .handle {
+ background: url('./handle.png') center;
+ display: inline-block;
+ height: 20px;
+ width: 20px;
+ cursor: grab;
+ cursor: -moz-grab;
+ cursor: -webkit-grab;
+ margin: 0;
+ }
+
+ .profile .types .type .delete {
+ background-position: left center;
+ height: 20px;
+ width: 20px;
+ visibility: hidden;
+ cursor: pointer;
+ }
+
+ .profile .types .type:hover:not(.is_empty) .delete {
+ visibility: visible;
+ }
\ No newline at end of file
diff --git a/couchpotato/core/plugins/profile/static/profile.js b/couchpotato/core/plugins/profile/static/profile.js
index 080f971..5bf268a 100644
--- a/couchpotato/core/plugins/profile/static/profile.js
+++ b/couchpotato/core/plugins/profile/static/profile.js
@@ -24,47 +24,32 @@ var Profile = new Class({
var data = self.data;
self.el = new Element('div.profile').adopt(
- self.header = new Element('h4', {'text': data.label}),
new Element('span.delete.icon', {
'events': {
'click': self.del.bind(self)
}
}),
- new Element('div', {
- 'class': 'ctrlHolder'
- }).adopt(
+ new Element('.quality_label.ctrlHolder').adopt(
new Element('label', {'text':'Name'}),
- new Element('input.label.textInput.large', {
+ new Element('input.inlay', {
'type':'text',
'value': data.label,
- 'events': {
- 'keyup': function(){
- self.header.set('text', this.get('value'))
- }
- }
+ 'placeholder': 'Profile name'
})
),
- new Element('div.ctrlHolder').adopt(
- new Element('label', {'text':'Wait'}),
- new Element('input.wait_for.textInput.xsmall', {
+ new Element('div.wait_for.ctrlHolder').adopt(
+ new Element('span', {'text':'Wait'}),
+ new Element('input.inlay.xsmall', {
'type':'text',
'value': data.types && data.types.length > 0 ? data.types[0].wait_for : 0
}),
- new Element('span', {'text':' day(s) for better quality.'})
+ new Element('span', {'text':'day(s) for a better quality.'})
),
- new Element('div.ctrlHolder').adopt(
- new Element('label', {'text': 'Qualities'}),
- new Element('div.head').adopt(
- new Element('span.quality_type', {'text': 'Search for'}),
- new Element('span.finish', {'html': 'Finish'})
- ),
+ new Element('div.qualities.ctrlHolder').adopt(
+ new Element('label', {'text': 'Search for'}),
self.type_container = new Element('ol.types'),
- new Element('a.addType', {
- 'text': 'Add another quality to search for.',
- 'href': '#',
- 'events': {
- 'click': self.addType.bind(self)
- }
+ new Element('div.formHint', {
+ 'html': "Search these qualities, from top to bottom.
Use the checkbox, if I don't have to search any further."
})
)
);
@@ -73,6 +58,8 @@ var Profile = new Class({
if(data.types)
Object.each(data.types, self.addType.bind(self))
+
+ self.addType();
},
save: function(delay){
@@ -96,6 +83,9 @@ var Profile = new Class({
}
}
});
+
+ self.addType();
+
}).delay(delay, self)
},
@@ -105,8 +95,8 @@ var Profile = new Class({
var data = {
'id' : self.data.id,
- 'label' : self.el.getElement('.label').get('value'),
- 'wait_for' : self.el.getElement('.wait_for').get('value'),
+ 'label' : self.el.getElement('.quality_label input').get('value'),
+ 'wait_for' : self.el.getElement('.wait_for input').get('value'),
'types': []
}
@@ -124,8 +114,19 @@ var Profile = new Class({
addType: function(data){
var self = this;
- var t = new Profile.Type(data);
+ var has_empty = false;
+ self.types.each(function(type){
+ if($(type).hasClass('is_empty'))
+ has_empty = true;
+ });
+
+ if(has_empty) return;
+
+ var t = new Profile.Type(data, {
+ 'onChange': self.save.bind(self, 0)
+ });
$(t).inject(self.type_container);
+
self.sortable.addItems($(t));
self.types.include(t);
@@ -135,23 +136,35 @@ var Profile = new Class({
del: function(){
var self = this;
- if(!confirm('Are you sure you want to delete this profile?')) return
-
- Api.request('profile.delete', {
- 'data': {
- 'id': self.data.id
- },
- 'useSpinner': true,
- 'spinnerOptions': {
- 'target': self.el
- },
- 'onComplete': function(json){
- if(json.success)
- self.el.destroy();
- else
- alert(json.message)
+ var label = self.el.getElement('.quality_label input').get('value');
+ new Question('Are you sure you want to delete "'+label+'"?', 'Items using this profile, will be set to the default quality.', [{
+ 'text': 'Delete "'+label+'"',
+ 'class': 'delete',
+ 'events': {
+ 'click': function(e){
+ (e).stop();
+ Api.request('profile.delete', {
+ 'data': {
+ 'id': self.data.id
+ },
+ 'useSpinner': true,
+ 'spinnerOptions': {
+ 'target': self.el
+ },
+ 'onComplete': function(json){
+ if(json.success)
+ self.el.destroy();
+ else
+ alert(json.message)
+ }
+ });
+ }
}
- });
+ }, {
+ 'text': 'Cancel',
+ 'cancel': true
+ }]);
+
},
makeSortable: function(){
@@ -180,16 +193,24 @@ var Profile = new Class({
});
-Profile.Type = Class({
+Profile.Type = new Class({
+
+ Implements: [Events, Options],
deleted: false,
- initialize: function(data){
+ initialize: function(data, options){
var self = this;
+ self.setOptions(options);
- self.data = data;
+ self.data = data || {};
self.create();
+ self.addEvent('change', function(){
+ self.el[self.qualities.get('value') == '-1' ? 'addClass' : 'removeClass']('is_empty');
+ self.deleted = self.qualities.get('value') == '-1';
+ });
+
},
create: function(){
@@ -201,10 +222,11 @@ Profile.Type = Class({
self.fillQualities()
),
new Element('span.finish').adopt(
- self.finish = new Element('input', {
- 'type':'checkbox',
- 'class':'finish',
- 'checked': data.finish
+ self.finish = new Element('input.inlay.finish[type=checkbox]', {
+ 'checked': data.finish,
+ 'events': {
+ 'change': self.fireEvent.bind(self, 'change')
+ }
})
),
new Element('span.delete.icon', {
@@ -213,14 +235,27 @@ Profile.Type = Class({
}
}),
new Element('span.handle')
- )
+ );
+
+ self.el[self.data.quality_id > 0 ? 'removeClass' : 'addClass']('is_empty');
+
+ new Form.Check(self.finish);
},
fillQualities: function(){
var self = this;
- self.qualities = new Element('select');
+ self.qualities = new Element('select', {
+ 'events': {
+ 'change': self.fireEvent.bind(self, 'change')
+ }
+ }).adopt(
+ new Element('option', {
+ 'text': '+ Add another quality',
+ 'value': -1
+ })
+ );
Object.each(Quality.qualities, function(q){
new Element('option', {
@@ -250,6 +285,8 @@ Profile.Type = Class({
self.el.addClass('deleted');
self.el.hide();
self.deleted = true;
+
+ self.fireEvent('change');
},
toElement: function(){
diff --git a/couchpotato/core/plugins/quality/static/quality.js b/couchpotato/core/plugins/quality/static/quality.js
index f11334c..71646aa 100644
--- a/couchpotato/core/plugins/quality/static/quality.js
+++ b/couchpotato/core/plugins/quality/static/quality.js
@@ -31,7 +31,7 @@ var QualityBase = new Class({
self.settings = App.getPage('Settings')
self.settings.addEvent('create', function(){
var tab = self.settings.createTab('profile', {
- 'label': 'Profile',
+ 'label': 'Profiles',
'name': 'profile'
});
@@ -52,10 +52,11 @@ var QualityBase = new Class({
var self = this;
self.settings.createGroup({
- 'label': 'Custom',
- 'description': 'Discriptions'
+ 'label': 'Quality Profiles',
+ 'description': 'Create your own profiles with multiple qualities.',
+ 'class': 'test123'
}).inject(self.content).adopt(
- new Element('a.add_new', {
+ new Element('a.add_new_profile', {
'text': 'Create a new quality profile',
'events': {
'click': function(){
@@ -96,11 +97,11 @@ var QualityBase = new Class({
var group = self.settings.createGroup({
'label': 'Sizes',
- 'description': 'Discriptions',
+ 'description': 'Edit the minimal and maximum sizes (in MB) for each quality.',
'advanced': true
}).inject(self.content)
- new Element('div.item.header').adopt(
+ new Element('div.item.head').adopt(
new Element('span.label', {'text': 'Quality'}),
new Element('span.min', {'text': 'Min'}),
new Element('span.max', {'text': 'Max'})
diff --git a/couchpotato/static/images/handle.png b/couchpotato/static/images/handle.png
deleted file mode 100644
index f78e248..0000000
Binary files a/couchpotato/static/images/handle.png and /dev/null differ
diff --git a/couchpotato/static/scripts/library/question.js b/couchpotato/static/scripts/library/question.js
new file mode 100644
index 0000000..63d3e97
--- /dev/null
+++ b/couchpotato/static/scripts/library/question.js
@@ -0,0 +1,81 @@
+var Question = new Class( {
+
+ initialize : function(question, hint, answers) {
+ var self = this
+
+ self.question = question
+ self.hint = hint
+ self.answers = answers
+
+ self.createQuestion()
+ self.answers.each(function(answer) {
+ self.createAnswer(answer)
+ })
+ self.createMask()
+
+ },
+
+ createMask : function() {
+ var self = this
+
+ $(document.body).mask( {
+ 'hideOnClick' : true,
+ 'destroyOnHide' : true,
+ 'onHide' : function() {
+ self.container.destroy();
+ }
+ }).show();
+ },
+
+ createQuestion : function() {
+
+ this.container = new Element('div', {
+ 'class' : 'question'
+ }).adopt(
+ new Element('h3', {
+ 'html': this.question
+ }),
+ new Element('div.hint', {
+ 'html': this.hint
+ })
+ ).inject(document.body)
+
+ this.container.position( {
+ 'position' : 'center'
+ });
+
+ },
+
+ createAnswer : function(options) {
+ var self = this
+
+ var answer = new Element('a', Object.merge(options, {
+ 'class' : 'answer button '+(options['class'] || '')+(options['cancel'] ? ' cancel' : '')
+ })).inject(this.container)
+
+ if (options.cancel) {
+ answer.addEvent('click', self.close.bind(self))
+ }
+ else if (options.request) {
+ answer.addEvent('click', function(e){
+ e.stop();
+ new Request(Object.merge(options, {
+ 'url': options.href,
+ 'onSuccess': function() {
+ (options.onSuccess || function(){})()
+ self.close();
+ }
+ })).send();
+ });
+ }
+ },
+
+ close : function() {
+ $(document.body).get('mask').destroy();
+ },
+
+ toElement : function() {
+ return this.container
+ }
+
+})
diff --git a/couchpotato/static/style/main.css b/couchpotato/static/style/main.css
index ec883c1..e0d9c38 100644
--- a/couchpotato/static/style/main.css
+++ b/couchpotato/static/style/main.css
@@ -345,3 +345,59 @@ form {
rgb(73,83,98) 100%
);
}
+
+.mask {
+ background: rgba(0,0,0, 0.7);
+ z-index: 100;
+}
+
+.question {
+ display: block;
+ width: 600px;
+ padding: 20px;
+ background: #f5f5f5;
+ position:fixed;
+ z-index:101;
+ text-align: center;
+ background: #5c697b;
+
+ border-radius: 3px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+
+ box-shadow: 0 0 50px rgba(0,0,0,0.55);
+ -moz-box-shadow: 0 0 50px rgba(0,0,0,0.55);
+ -webkit-box-shadow: 0 0 50px rgba(0,0,0,0.55);
+}
+
+ .question h3 {
+ font-size: 25px;
+ padding: 0;
+ margin: 0 0 20px;
+ }
+
+ .question .hint {
+ font-size: 14px;
+ color: #ccc;
+ text-shadow: none;
+ }
+
+ .question .answer {
+ font-size: 17px;
+ display: inline-block;
+ padding: 10px;
+ margin: 5px 1%;
+ cursor: pointer;
+ width: auto;
+ }
+ .question .answer:hover {
+ background: #f1f1f1;
+ }
+
+ .question .answer.delete {
+ background-color: #a82f12;
+ }
+ .question .answer.cancel {
+ margin-top: 20px;
+ background-color: #4c5766;
+ }
diff --git a/couchpotato/static/style/page/settings.css b/couchpotato/static/style/page/settings.css
index ff7fd14..2ce8954 100644
--- a/couchpotato/static/style/page/settings.css
+++ b/couchpotato/static/style/page/settings.css
@@ -149,6 +149,8 @@
margin: 0;
padding: 6px 0 0;
}
+
+ .page.settings .xsmall { width: 20px !important; text-align: center; }
.page.settings input[type=text], .page.settings input[type=password] {
padding: 5px 3px;
diff --git a/couchpotato/templates/_desktop.html b/couchpotato/templates/_desktop.html
index fe9b0c9..be98a3d 100644
--- a/couchpotato/templates/_desktop.html
+++ b/couchpotato/templates/_desktop.html
@@ -16,6 +16,7 @@
+