Movie search

Profile Settings
This commit is contained in:
Ruud
2011-03-20 22:12:33 +01:00
parent cc260d3a07
commit 288aa8c0a1
34 changed files with 1408 additions and 178 deletions
+100 -9
View File
@@ -35,6 +35,9 @@ Block.Search = new Class({
self.OuterClickStack = new EventStack.OuterClick();
//debug
//self.input.set('value', 'kick ass')
//self.autocomplete()
},
clear: function(e){
@@ -98,7 +101,7 @@ Block.Search = new Class({
self.hideResults(false)
if(!cache){
self.api_request = Api.request('movie.add.search', {
self.api_request = Api.request('movie.search', {
'data': {
'q': q
},
@@ -118,7 +121,7 @@ Block.Search = new Class({
self.spinner.hide();
self.cache[q] = json
self.movies = []
self.movies = {}
self.results.empty()
Object.each(json.movies, function(movie){
@@ -126,9 +129,14 @@ Block.Search = new Class({
if(!movie.imdb || (movie.imdb && !self.results.getElement('#'+movie.imdb))){
var m = new Block.Search.Item(movie);
$(m).inject(self.results)
self.movies[movie.imdb || 'r-'+Math.floor(Math.random()*10000)] = m
}
else {
self.movies[movie.imdb].alternativeName({
'name': movie.name
})
}
self.movies.include(m)
});
},
@@ -149,6 +157,7 @@ Block.Search.Item = new Class({
var self = this;
self.info = info;
self.alternative_names = [];
self.create();
@@ -163,11 +172,7 @@ Block.Search.Item = new Class({
self.el = new Element('div.movie', {
'id': info.imdb
}).adopt(
new Element('div.add').adopt(
new Element('span', {
'text': 'test'
})
),
self.options = new Element('div.options'),
self.data_container = new Element('div.data', {
'tween': {
duration: 400,
@@ -208,11 +213,23 @@ Block.Search.Item = new Class({
}).inject(self.starring)
})
}
self.alternativeName({
'name': info.name
});
},
alternativeName: function(alternative){
var self = this;
self.alternative_names.include(alternative);
},
showOptions: function(){
var self = this;
self.createOptions();
if(!self.width)
self.width = self.data_container.getCoordinates().width
@@ -222,6 +239,80 @@ Block.Search.Item = new Class({
},
add: function(e){
var self = this;
(e).stop();
Api.request('movie.add', {
'data': {
'identifier': self.info.imdb,
'name': self.name_select.get('value'),
'quality': self.quality_select.get('value')
},
'useSpinner': true,
'spinnerTarget': self.options,
'onComplete': function(){
self.options.empty();
self.options.adopt(
new Element('div.message', {
'text': 'Movie succesfully added.'
})
);
},
'onFailure': function(){
self.options.empty();
self.options.adopt(
new Element('div.message', {
'text': 'Something went wrong, check the logs for more info.'
})
);
}
});
},
createOptions: function(){
var self = this;
if(!self.options.hasClass('set')){
self.options.adopt(
new Element('div').adopt(
self.info.poster ? new Element('img.thumbnail', {
'src': self.info.poster
}) : null,
self.name_select = new Element('select', {
'name': 'name'
}),
self.quality_select = new Element('select', {
'name': 'profile_identifier'
}),
new Element('a.button', {
'text': 'Add',
'events': {
'click': self.add.bind(self)
}
})
)
);
Array.each(self.alternative_names, function(alt){
new Element('option', {
'text': alt.name
}).inject(self.name_select)
})
Array.each(Quality.profiles, function(q){
new Element('option', {
'value': q.indentifier,
'text': q.label
}).inject(self.quality_select)
});
self.options.addClass('set');
}
},
closeOptions: function(){
var self = this;
@@ -232,4 +323,4 @@ Block.Search.Item = new Class({
return this.el
}
})
});
+9 -3
View File
@@ -1,6 +1,6 @@
var CouchPotato = new Class({
Implements: [Options],
Implements: [Events, Options],
defaults: {
page: 'wanted',
@@ -11,7 +11,7 @@ var CouchPotato = new Class({
pages: [],
block: [],
initialize: function(options) {
setup: function(options) {
var self = this;
self.setOptions(options);
@@ -62,6 +62,8 @@ var CouchPotato = new Class({
$(pg).inject(self.content);
});
self.fireEvent('load')
},
openPage: function(url) {
@@ -85,9 +87,13 @@ var CouchPotato = new Class({
getBlock: function(block_name){
return this.block[block_name]
},
getPage: function(name){
return this.pages[name]
}
});
window.App = new CouchPotato();
var ApiClass = new Class({
+54 -32
View File
@@ -105,20 +105,7 @@ Page.Settings = new Class({
// Create tabs
Object.each(self.tabs, function(tab, tab_name){
if(!self.tabs[tab_name].tab){
var tab_el = new Element('li').adopt(
new Element('a', {
'href': '/'+self.name+'/'+tab_name+'/',
'text': tab.label.capitalize()
})
).inject(self.tabs_container);
self.tabs[tab_name] = Object.merge(self.tabs[tab_name], {
'tab': tab_el,
'content': new Element('div.tab_content').inject(self.containers),
'groups': {}
})
}
self.createTab(tab_name, tab)
});
// Add content to tabs
@@ -128,17 +115,7 @@ Page.Settings = new Class({
section.groups.sortBy('order').each(function(group){
// Create the group
var group_el = new Element('fieldset', {
'class': group.advanced ? 'inlineLabels advanced' : 'inlineLabels'
}).adopt(
new Element('h2', {
'text': group.label
}).adopt(
new Element('span.hint', {
'text': group.description
})
)
).inject(self.tabs[group.tab].content);
var group_el = self.createGroup(group).inject(self.tabs[group.tab].content);
self.tabs[group.tab].groups[group.name] = group_el
@@ -152,8 +129,57 @@ Page.Settings = new Class({
});
});
self.fireEvent('create');
self.openTab();
},
createTab: function(tab_name, tab){
var self = this;
if(self.tabs[tab_name] && self.tabs[tab_name].tab)
return self.tabs[tab_name].tab
var tab_el = new Element('li').adopt(
new Element('a', {
'href': '/'+self.name+'/'+tab_name+'/',
'text': tab.label.capitalize()
})
).inject(self.tabs_container);
if(!self.tabs[tab_name])
self.tabs[tab_name] = {
'label': tab.label
}
self.tabs[tab_name] = Object.merge(self.tabs[tab_name], {
'tab': tab_el,
'content': new Element('div.tab_content').inject(self.containers),
'groups': {}
})
return self.tabs[tab_name]
},
createGroup: function(group){
var self = this;
var group_el = new Element('fieldset', {
'class': group.advanced ? 'inlineLabels advanced' : 'inlineLabels'
}).adopt(
new Element('h2', {
'text': group.label
}).adopt(
new Element('span.hint', {
'text': group.description
})
)
)
return group_el
}
});
@@ -226,7 +252,7 @@ var OptionBase = new Class({
save: function(){
var self = this;
self.api().request('setting.save', {
Api.request('setting.save', {
'data': {
'section': self.section,
'name': self.name,
@@ -273,10 +299,6 @@ var OptionBase = new Class({
return self.page.getValue(self.section, self.name);
},
api: function(){
return this.page.api();
},
inject: function(el, position){
this.el.inject(el, position);
return this.el;
@@ -448,7 +470,7 @@ Option.Directory = new Class({
self.fillBrowser()
}
else {
self.api().request('directory.list', {
Api.request('directory.list', {
'data': {
'path': c
},
@@ -461,7 +483,7 @@ Option.Directory = new Class({
var self = this;
var v = self.input.get('value');
var sep = self.api().getOption('path_sep');
var sep = Api.getOption('path_sep');
var dirs = v.split(sep);
dirs.pop();
+317
View File
@@ -0,0 +1,317 @@
var QualityBase = new Class({
tab: '',
content: '',
setup: function(data){
var self = this;
self.profiles = data.profiles;
self.qualities = data.qualities;
App.addEvent('load', self.addSettings.bind(self))
},
addSettings: function(){
var self = this;
self.settings = App.getPage('Settings')
self.settings.addEvent('create', function(){
var tab = self.settings.createTab('profile', {
'label': 'Profile',
'name': 'profile'
});
self.tab = tab.tab;
self.content = tab.content;
self.createProfiles();
self.createOrdering();
self.createSizes();
})
},
/**
* Profiles
*/
createProfiles: function(){
var self = this;
self.settings.createGroup({
'label': 'Custom',
'description': 'Discriptions'
}).inject(self.content).adopt(
new Element('a.add_new', {
'text': 'Create a new quality profile',
'events': {
'click': self.createNewProfile.bind(self)
}
}),
self.profile_container = new Element('div.container')
)
Object.each(self.profiles, self.createNewProfile.bind(self))
},
createNewProfile: function(data, nr){
var self = this;
self.profiles[nr] = new Profile(data);
$(self.profiles[nr]).inject(self.profile_container)
},
/**
* Ordering
*/
createOrdering: function(){
var self = this;
self.settings.createGroup({
'label': 'Order',
'description': 'Discriptions'
}).inject(self.content)
},
/**
* Sizes
*/
createSizes: function(){
var self = this;
self.settings.createGroup({
'label': 'Sizes',
'description': 'Discriptions',
'advanced': true
}).inject(self.content)
}
});
window.Quality = new QualityBase();
var Profile = new Class({
data: {},
types: [],
initialize: function(data){
var self = this;
self.data = data;
self.types = [];
self.create();
self.el.addEvents({
'change:relay(select, input[type=checkbox])': self.save.bind(self, 0),
'keyup:relay(input[type=text])': self.save.bind(self, [300])
});
},
create: function(){
var self = this;
var data = self.data;
self.el = new Element('div', {
'class': 'profile'
}).adopt(
new Element('h4', {'text': data.label}),
new Element('span.delete', {
'html': 'del',
'events': {
'click': self.del.bind(self)
}
}),
new Element('div', {
'class': 'ctrlHolder'
}).adopt(
new Element('label', {'text':'Name'}),
new Element('input.label.textInput.large', {
'type':'text',
'value': data.label
})
),
new Element('div.ctrlHolder').adopt(
new Element('label', {'text':'Wait'}),
new Element('input.wait_for.textInput.xsmall', {
'type':'text',
'value': data.wait_for
}),
new Element('span', {'text':' day(s) for better quality.'})
),
new Element('div.ctrlHolder').adopt(
new Element('label', {'text': 'Qualities'}),
self.type_container = new Element('div.types').adopt(
new Element('div.head').adopt(
new Element('span.quality_type', {'text': 'Search for'}),
new Element('span.finish', {'html': '<acronym title="Won\'t download anything else if it has found this quality.">Finish</acronym>'})
)
),
new Element('a.addType', {
'text': 'Add another quality to search for.',
'href': '#',
'events': {
'click': self.addType.bind(self)
}
})
)
);
if(data.types)
Object.each(data.types, self.addType.bind(self))
},
save: function(delay){
var self = this;
if(self.save_timer) clearTimeout(self.save_timer);
self.save_timer = (function(){
Api.request('profile.save', {
'data': self.getData(),
'useSpinner': true,
'spinnerOptions': {
'target': self.el
}
});
}).delay(delay, self)
},
getData: function(){
var self = this;
var data = {
'id' : self.data.id,
'label' : self.el.getElement('.label').get('value'),
'wait_for' : self.el.getElement('.wait_for').get('value'),
'types': []
}
Object.each(self.types, function(type){
if(!type.deleted)
data.types.include(type.getData());
})
return data
},
addType: function(data){
var self = this;
var t = new Profile.Type(data);
$(t).inject(self.type_container);
self.types.include(t);
},
del: function(){
var self = this;
Api.request('profile.delete', {
'data': {
'id': self.data.id
},
'useSpinner': true,
'spinnerOptions': {
'target': self.el
},
'onComplete': function(){
self.el.destroy();
}
});
},
toElement: function(){
return this.el
}
});
Profile.Type = Class({
deleted: false,
initialize: function(data){
var self = this;
self.data = data;
self.create();
},
create: function(){
var self = this;
var data = self.data;
self.el = new Element('div.type').adopt(
new Element('span.quality_type').adopt(
self.fillQualities()
),
new Element('span.finish').adopt(
self.finish = new Element('input', {
'type':'checkbox',
'class':'finish',
'checked': data.finish
})
),
new Element('span.delete', {
'html': 'del',
'events': {
'click': self.del.bind(self)
}
}),
new Element('span', {
'class':'handle'
})
)
},
fillQualities: function(){
var self = this;
self.qualities = new Element('select');
Object.each(Quality.qualities, function(q){
new Element('option', {
'text': q.label,
'value': q.identifier
}).inject(self.qualities)
});
self.qualities.set('value', self.data.quality);
return self.qualities;
},
getData: function(){
var self = this;
return {
'quality': self.qualities.get('value'),
'finish': +self.finish.checked
}
},
del: function(){
var self = this;
self.el.hide();
self.deleted = true;
},
toElement: function(){
return this.el;
}
})