You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

643 lines
12 KiB

Page.Settings = new Class({
Extends: PageBase,
name: 'settings',
title: 'Change settings.',
tabs: {
'general': {},
'searcher': {},
'providers': {},
'downloaders': {},
'notifications': {},
'renamer': {}
},
open: function(action, params){
var self = this
self.action = action;
self.params = params;
if(!self.data)
self.getData(self.create.bind(self))
else
self.openTab(action);
},
openTab: function(action){
var self = this;
var action = action || self.action;
if(self.current)
self.toggleTab(self.current, true);
var tab = self.toggleTab(action)
self.current = tab == self.tabs.general ? 'general' : action;
},
toggleTab: function(tab_name, hide){
var self = this;
var a = hide ? 'removeClass' : 'addClass';
var c = 'active';
var t = self.tabs[tab_name] || self.tabs[self.action] || self.tabs.general;
t.tab[a](c);
t.content[a](c);
return t
},
getData: function(onComplete){
var self = this;
if(onComplete)
Api.request('settings', {
'useSpinner': true,
'spinnerOptions': {
'target': self.el
},
'onComplete': function(json){
self.data = json;
onComplete(json);
}
})
return self.data;
},
getValue: function(section, name){
var self = this;
try {
return self.data.values[section][name];
}
catch(e){
return ''
}
},
showAdvanced: function(){
var self = this;
var c = self.advanced_toggle.checked ? 'addClass' : 'removeClass';
self.el[c]('show_advanced')
},
create: function(json){
var self = this
self.el.adopt(
self.tabs_container = new Element('ul.tabs'),
self.containers = new Element('form.uniForm.containers').adopt(
new Element('label.advanced_toggle').adopt(
new Element('span', {
'text': 'Show advanced settings'
}),
self.advanced_toggle = new Element('input[type=checkbox].inlay', {
'events': {
'change': self.showAdvanced.bind(self)
}
})
)
)
);
new Form.Check(self.advanced_toggle, {
'onChange': self.showAdvanced.bind(self)
})
// Create tabs
Object.each(self.tabs, function(tab, tab_name){
self.createTab(tab_name, tab)
});
// Add content to tabs
Object.each(json.options, function(section, section_name){
// Add groups to content
section.groups.sortBy('order').each(function(group){
// Create the group
if(!self.tabs[group.tab].groups[group.name]){
var group_el = self.createGroup(group).inject(self.tabs[group.tab].content);
self.tabs[group.tab].groups[group.name] = group_el
}
// Add options to group
group.options.sortBy('order').each(function(option){
var class_name = (option.type || 'string').capitalize();
var input = new Option[class_name](self, section_name, option.name, option);
input.inject(self.tabs[group.tab].groups[group.name]);
input.fireEvent('injected')
});
});
});
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 label = (tab.label || tab.name || tab_name).capitalize()
var tab_el = new Element('li').adopt(
new Element('a', {
'href': '/'+self.name+'/'+tab_name+'/',
'text': label
}).adopt()
).inject(self.tabs_container);
if(!self.tabs[tab_name])
self.tabs[tab_name] = {
'label': 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 || group.name).capitalize()
}).adopt(
new Element('span.hint', {
'html': group.description
})
)
)
return group_el
}
});
var OptionBase = new Class({
Implements: [Options, Events],
klass: 'textInput',
focused_class : 'focused',
save_on_change: true,
initialize: function(parent, section, name, options){
var self = this
self.setOptions(options)
self.page = parent;
self.section = section;
self.name = name;
self.createBase();
self.create();
self.createHint();
self.setAdvanced();
// Add focus events
self.input.addEvents({
'change': self.changed.bind(self),
'keyup': self.changed.bind(self)
});
self.addEvent('injected', self.afterInject.bind(self))
},
/**
* Create the element
*/
createBase: function(){
var self = this
self.el = new Element('div.ctrlHolder')
},
create: function(){},
createLabel: function(){
var self = this;
return new Element('label', {
'text': (self.options.label || self.options.name).capitalize()
})
},
setAdvanced: function(){
this.el.addClass(this.options.advanced ? 'advanced': '')
},
createHint: function(){
var self = this;
if(self.options.description)
new Element('p.formHint', {
'html': self.options.description
}).inject(self.el);
},
afterInject: function(){},
// Element has changed, do something
changed: function(){
var self = this;
if(self.getValue() != self.previous_value){
if(self.save_on_change){
if(self.changed_timer) clearTimeout(self.changed_timer);
self.changed_timer = self.save.delay(300, self);
}
self.fireEvent('change')
}
},
save: function(){
var self = this;
Api.request('settings.save', {
'data': {
'section': self.section,
'name': self.name,
'value': self.getValue()
},
'useSpinner': true,
'spinnerOptions': {
'target': self.el
},
'onComplete': self.saveCompleted.bind(self)
});
},
saveCompleted: function(json){
var self = this;
var sc = json.success ? 'save_success' : 'save_failed';
self.previous_value = self.getValue();
self.el.addClass(sc);
(function(){
self.el.removeClass(sc);
}).delay(3000, self);
},
setName: function(name){
this.name = name;
},
postName: function(){
var self = this;
return self.section +'['+self.name+']';
},
getValue: function(){
var self = this;
return self.input.get('value');
},
getSettingValue: function(){
var self = this;
return self.page.getValue(self.section, self.name);
},
inject: function(el, position){
this.el.inject(el, position);
return this.el;
},
toElement: function(){
return this.el;
}
})
var Option = {}
Option.String = new Class({
Extends: OptionBase,
type: 'string',
create: function(){
var self = this
self.el.adopt(
self.createLabel(),
self.input = new Element('input.inlay', {
'type': 'text',
'name': self.postName(),
'value': self.getSettingValue()
})
);
}
});
Option.Dropdown = new Class({
Extends: OptionBase,
create: function(){
var self = this
self.el.adopt(
self.createLabel(),
self.input = new Element('select', {
'name': self.postName()
})
)
Object.each(self.options.values, function(value){
new Element('option', {
'text': value[0],
'value': value[1]
}).inject(self.input)
})
self.input.set('value', self.getSettingValue());
var dd = new Form.Dropdown(self.input, {
'onChange': self.changed.bind(self)
});
self.input = dd.input;
}
});
Option.Checkbox = new Class({
Extends: OptionBase,
type: 'checkbox',
create: function(){
var self = this;
var randomId = 'r-'+randomString()
self.el.adopt(
self.createLabel().set('for', randomId),
self.input = new Element('input.inlay', {
'name': self.postName(),
'type': 'checkbox',
'checked': self.getSettingValue(),
'id': randomId
})
);
new Form.Check(self.input, {
'onChange': self.changed.bind(self)
});
},
getValue: function(){
var self = this;
return +self.input.checked;
}
});
Option.Password = new Class({
Extends: Option.String,
type: 'password',
create: function(){
var self = this;
self.parent()
self.input.set('type', 'password')
}
});
Option.Bool = new Class({
Extends: Option.Checkbox
});
Option.Enabler = new Class({
Extends: Option.Bool,
create: function(){
var self = this;
self.el.adopt(
self.input = new Element('input.inlay', {
'type': 'checkbox',
'checked': self.getSettingValue(),
'id': 'r-'+randomString(),
'events': {
'change': self.checkState.bind(self)
}
})
);
new Form.Check(self.input, {
'onChange': self.changed.bind(self)
});
},
changed: function(){
this.parent();
this.checkState();
},
checkState: function(){
var self = this;
self.parentFieldset[ self.getValue() ? 'removeClass' : 'addClass']('disabled');
},
afterInject: function(){
var self = this;
self.parentFieldset = self.el.getParent('fieldset')
self.el.inject(self.parentFieldset, 'top')
self.checkState()
}
});
Option.Int = new Class({
Extends: Option.String
});
Option.Directory = new Class({
Extends: OptionBase,
type: 'span',
browser: '',
save_on_change: false,
create: function(){
var self = this;
self.el.adopt(
self.createLabel(),
self.input = new Element('span.directory', {
'text': self.getSettingValue(),
'events': {
'click': self.showBrowser.bind(self)
}
})
);
self.cached = {};
},
selectDirectory: function(e, el){
var self = this;
self.input.set('text', el.get('data-value'));
self.getDirs()
self.fireEvent('change')
},
previousDirectory: function(e){
var self = this;
self.selectDirectory(null, self.back_button)
},
showBrowser: function(){
var self = this;
if(!self.browser)
self.browser = new Element('div.directory_list').adopt(
new Element('div.actions').adopt(
self.back_button = new Element('a.button.back', {
'text': '',
'events': {
'click': self.previousDirectory.bind(self)
}
}),
new Element('label', {
'text': 'Show hidden files'
}).adopt(
self.show_hidden = new Element('input[type=checkbox].inlay')
)
),
self.dir_list = new Element('ul', {
'events': {
'click:relay(li)': self.selectDirectory.bind(self)
}
}),
new Element('div.actions').adopt(
new Element('a.button.cancel', {
'text': 'Cancel',
'events': {
'click': self.hideBrowser.bind(self)
}
}),
new Element('span', {
'text': 'or'
}),
self.save_button = new Element('a.button.save', {
'text': 'Save',
'events': {
'click': self.hideBrowser.bind(self, true)
}
})
)
).inject(self.input, 'after')
self.getDirs()
self.browser.show()
self.el.addEvent('outerClick', self.hideBrowser.bind(self))
},
hideBrowser: function(save){
var self = this;
if(save) self.save()
self.browser.hide()
self.el.removeEvent('outerClick', self.hideBrowser.bind(self))
},
fillBrowser: function(json){
var self = this;
var c = self.getParentDir();
var v = self.input.get('text');
var previous_dir = self.getParentDir(c.substring(0, c.length-1));
if(previous_dir){
self.back_button.set('data-value', previous_dir)
self.back_button.set('text', self.getCurrentDirname(previous_dir))
self.back_button.show()
}
else {
self.back_button.hide()
}
if(!json)
json = self.cached[c];
else
self.cached[c] = json;
self.dir_list.empty();
json.dirs.each(function(dir){
if(dir.indexOf(v) != -1){
new Element('li', {
'data-value': dir,
'text': self.getCurrentDirname(dir)
}).inject(self.dir_list)
}
})
},
getDirs: function(){
var self = this;
var c = self.getParentDir();
if(self.cached[c]){
self.fillBrowser()
}
else {
Api.request('directory.list', {
'data': {
'path': c,
'show_hidden': +self.show_hidden.checked
},
'onComplete': self.fillBrowser.bind(self)
})
}
},
getParentDir: function(dir){
var self = this;
var v = dir || self.input.get('text');
var sep = Api.getOption('path_sep');
var dirs = v.split(sep);
dirs.pop();
return dirs.join(sep) + sep
},
getCurrentDirname: function(dir){
var self = this;
var dir_split = dir.split(Api.getOption('path_sep'));
return dir_split[dir_split.length-2] || '/'
},
getValue: function(){
var self = this;
return self.input.get('text');
}
});