Renamer, movie searcher, Library scanning

New theme for UI
and more..
This commit is contained in:
Ruud
2011-05-28 20:52:18 +02:00
parent e0b3c27957
commit 98aafeaec3
37 changed files with 2407 additions and 869 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,51 @@
/*
---
name: Form.CheckGroup
description: Class to represent a group of Form.Check wrapped checkboxes
authors: Bryan J Swift (@bryanjswift)
license: MIT-style license.
requires: [Core/Class.Extras, Core/Element, Core/Element.Event, Form-Replacement/Form.Check]
provides: Form.CheckGroup
...
*/
if (typeof window.Form === 'undefined') { window.Form = {}; }
Form.CheckGroup = new Class({
Implements: [Events,Options],
options: {
checkOptions: {},
initialValues: {}
},
checks: [],
initialize: function(group,options) {
if (!Form.Check) { throw 'required Class Form.Check not found'; }
this.setOptions(options);
group = $(group);
if (!group) { return this; }
var checkboxes = group.getElements('input[type=checkbox]');
checkboxes.each(this.addCheck,this);
},
addCheck: function(checkbox) {
var initialValues = this.options.initialValues[checkbox.get('name')];
var checkOptions = {};
checkOptions.checked = initialValues ? initialValues.contains(checkbox.get('value')) : checkbox.get('checked');
checkOptions.disabled = checkbox.get('disabled');
checkbox.store('Form.CheckGroup::data',this);
var check = checkbox.retrieve('Form.Check::data') || new Form.Check(checkbox, Object.append(checkOptions,this.options.checkOptions));
this.checks.push(check);
},
checkAll: function() {
this.checks.each(function(check) { if (!check.checked) { check.toggle(); } });
},
disable: function() {
this.checks.each(function(check) { check.disable(); });
this.fireEvent('disable',this);
},
enable: function() {
this.checks.each(function(check) { check.enable(); });
this.fireEvent('enable',this);
},
uncheckAll: function() {
this.checks.each(function(check) { if (check.checked) { check.toggle(); } });
}
});
@@ -0,0 +1,59 @@
/*
---
name: Form.RadioGroup
description: Class to represent a group of Form.Radio buttons
authors: Bryan J Swift (@bryanjswift)
license: MIT-style license.
requires: [Core/Class.Extras, Core/Element, Core/Element.Event, Form-Replacement/Form.Radio]
provides: Form.RadioGroup
...
*/
if (typeof window.Form === 'undefined') { window.Form = {}; }
Form.RadioGroup = new Class({
Implements: [Events,Options],
options: {
radioOptions: {},
initialValues: {}
},
bound: {},
radios: [],
value: null,
initialize: function(group,options) {
if (!Form.Radio) { throw 'required Class Form.Radio not found'; }
this.setOptions(options);
this.bound = { select: this.select.bind(this) };
group = $(group);
if (!group) { return this; }
var radios = group.getElements('input[type=radio]');
radios.each(this.addCheck,this);
},
addCheck: function(radio,i) {
var initialValues = this.options.initialValues[radio.get('name')];
var radioOptions = {};
radioOptions.checked = initialValues ? initialValues.contains(radio.get('value')) : radio.get('checked');
radioOptions.disabled = radio.get('disabled');
var check = (radio.retrieve('Form.Radio::data')
|| new Form.Radio(radio,Object.append(radioOptions,this.options.radioOptions)));
check.addEvent('onCheck',this.bound.select);
if (check.checked) { i ? this.changed(check) : this.value = check.value; }
radio.store('Form.RadioGroup::data',this);
this.radios.push(check);
},
changed: function(radio) {
this.value = radio.value;
this.fireEvent('onChange',this);
},
disable: function() {
this.radios.each(function(radio) { radio.disable(); });
},
enable: function() {
this.radios.each(function(radio) { radio.enable(); });
},
select: function(checkedRadio) {
this.radios.each(function(radio) {
if (radio.checked && radio.value !== checkedRadio.value) { radio.uncheck(); }
});
if (checkedRadio.value !== this.value) { this.changed(checkedRadio); }
}
});
@@ -0,0 +1,125 @@
/*
---
name: Form.Check
description: Class to represent a checkbox
authors: Bryan J Swift (@bryanjswift)
license: MIT-style license.
requires: [Core/Class.Extras, Core/Element, Core/Element.Event]
provides: Form.Check
...
*/
if (typeof window.Form === 'undefined') { window.Form = {}; }
Form.Check = new Class({
Implements: [Events, Options],
options: {
checked: false,
disabled: false
},
bound: {},
checked: false,
config: {
checkedClass: 'checked',
disabledClass: 'disabled',
elementClass: 'check',
highlightedClass: 'highlighted',
storage: 'Form.Check::data'
},
disabled: false,
element: null,
input: null,
label: null,
value: null,
initialize: function(input, options) {
this.setOptions(options);
this.bound = {
disable: this.disable.bind(this),
enable: this.enable.bind(this),
highlight: this.highlight.bind(this),
removeHighlight: this.removeHighlight.bind(this),
keyToggle: this.keyToggle.bind(this),
toggle: this.toggle.bind(this)
};
var bound = this.bound;
input = this.input = $(input);
var id = input.get('id');
this.label = document.getElement('label[for=' + id + ']');
this.element = new Element('div', {
'class': input.get('class') + ' ' + this.config.elementClass,
id: id ? id + 'Check' : '',
events: {
click: bound.toggle,
mouseenter: bound.highlight,
mouseleave: bound.removeHighlight
}
});
this.input.addEvents({
keypress: bound.keyToggle,
keydown: bound.keyToggle,
keyup: bound.keyToggle
});
if (this.label) { this.label.addEvent('click', bound.toggle); }
this.element.wraps(input);
this.value = input.get('value');
if (this.input.checked) { this.check(); } else { this.uncheck(); }
if (this.input.disabled) { this.disable(); } else { this.enable(); }
input.store(this.config.storage, this).addEvents({
blur: bound.removeHighlight,
focus: bound.highlight
});
this.fireEvent('create', this);
},
check: function() {
this.element.addClass(this.config.checkedClass);
this.input.set('checked', 'checked').focus();
this.checked = true;
this.fireEvent('check', this);
},
disable: function() {
this.element.addClass(this.config.disabledClass);
this.input.set('disabled', 'disabled');
this.disabled = true;
this.fireEvent('disable', this);
},
enable: function() {
this.element.removeClass(this.config.disabledClass);
this.input.erase('disabled');
this.disabled = false;
this.fireEvent('enable', this);
},
highlight: function() {
this.element.addClass(this.config.highlightedClass);
this.fireEvent('highlight', this);
},
removeHighlight: function() {
this.element.removeClass(this.config.highlightedClass);
this.fireEvent('removeHighlight', this);
},
keyToggle: function(e) {
var evt = new Event(e);
if (evt.key === 'space') { this.toggle(e); }
},
toggle: function(e) {
var evt;
if (this.disabled) { return this; }
if (e) {
evt = new Event(e).stopPropagation();
if (evt.target.tagName.toLowerCase() !== 'a') {
evt.stop();
}
}
if (this.checked) {
this.uncheck();
} else {
this.check();
}
this.fireEvent('change', this);
return this;
},
uncheck: function() {
this.element.removeClass(this.config.checkedClass);
this.input.erase('checked');
this.checked = false;
this.fireEvent('uncheck', this);
}
});
@@ -0,0 +1,325 @@
/*
---
name: Form.Dropdown
description: Class to represent a select input
authors: Bryan J Swift (@bryanjswift)
license: MIT-style license.
requires: [Core/Class.Extras, Core/Element, Core/Element.Event, Form-Replacement/Form.SelectOption]
provides: Form.Dropdown
...
*/
if (typeof window.Form === 'undefined') { window.Form = {}; }
Form.Dropdown = new Class({
Implements: [Events,Options],
options: {
excludedValues: [],
initialValue: null,
mouseLeaveDelay: 350,
selectOptions: {},
typeDelay: 500
},
bound: {},
dropdownOptions: [],
element: null,
events: {},
highlighted: null,
input: null,
open: true,
selected: null,
selection: null,
typed: { lastKey: null, value: null, timer: null, pressed: null, shortlist: [], startkey: null },
value: null,
initialize: function(select,options) {
this.setOptions(options);
select = $(select);
this.bound = {
collapse: this.collapse.bind(this),
expand: this.expand.bind(this),
focus: this.focus.bind(this),
highlightOption: this.highlightOption.bind(this),
keydown: this.keydown.bind(this),
keypress: this.keypress.bind(this),
mouseenterDropdown: this.mouseenterDropdown.bind(this),
mouseleaveDropdown: this.mouseleaveDropdown.bind(this),
mousemove: this.mousemove.bind(this),
removeHighlightOption: this.removeHighlightOption.bind(this),
select: this.select.bind(this),
toggle: this.toggle.bind(this)
};
this.events = { mouseenter: this.bound.mouseenterDropdown, mouseleave: this.bound.mouseleaveDropdown };
this.value = this.options.initialValue;
this.initializeCreateElements(select);
var optionElements = select.getElements('option');
this.updateOptions(optionElements);
this.element.replaces(select);
document.addEvent('click', this.bound.collapse);
var eventName = Browser.ie || Browser.webkit ? 'keydown' : 'keypress';
var target = Browser.ie ? $(document.body) : window;
target.addEvent('keydown',this.bound.keydown).addEvent(eventName,this.bound.keypress);
},
initializeCreateElements: function(select) {
var id = select.get('id');
var dropdown = new Element('div', {
'class': (select.get('class') + ' select').trim(),
'id': (id && id !== '') ? id + 'Dropdown' : ''
});
var menu = new Element('div', {'class': 'menu'});
var list = new Element('div', {'class': 'list'});
var options = new Element('ul', {'class': 'options'});
dropdown.adopt(menu.adopt(list.adopt(options)));
var dropdownSelection = new Element('div', {
'class': 'selection',
events: {click: this.bound.toggle}
});
var dropdownBackground = new Element('div', { 'class': 'dropdownBackground' });
var selection = new Element('span', { 'class': 'selectionDisplay' });
var input = new Element('input', {
type:'text',
id: id,
name: select.get('name'),
events: {
focus: this.bound.focus
}
});
dropdownSelection.adopt(dropdownBackground, selection, input);
dropdown.adopt(dropdownSelection);
this.element = dropdown;
this.selection = selection;
this.input = input;
return options;
},
collapse: function(e) {
this.open = false;
this.element.removeClass('active').removeClass('dropdown-active');
if (this.selected) { this.selected.removeHighlight(); }
this.element.removeEvents(this.events);
this.fireEvent('collapse', [this, e]);
},
deselect: function(option) {
option.deselect();
},
destroy: function() {
this.element = null;
this.selection = null;
this.input = null;
},
disable: function() {
this.collapse();
this.input.set('disabled', 'disabled').removeEvents({blur:this.bound.blur, focus:this.bound.focus});
this.selection.getParent().removeEvent('click', this.bound.toggle);
this.fireEvent('disable', this);
},
enable: function() {
this.input.erase('disabled').addEvents({blur:this.bound.blur, focus:this.bound.focus});
this.selection.getParent().addEvent('click', this.bound.toggle);
this.fireEvent('enable', this);
},
expand: function(e) {
clearTimeout(this.collapseInterval);
var evt = e ? new Event(e).stop() : null;
this.open = true;
this.input.focus();
this.element.addClass('active').addClass('dropdown-active');
if (this.selected) { this.selected.highlight(); }
this.element.addEvents(this.events);
this.fireEvent('expand', [this, e]);
},
focus: function(e) {
this.expand();
},
foundMatch: function(e) {
var typed = this.typed;
var shortlist = typed.shortlist;
var value = typed.value;
var i = 0;
var optionsLength = shortlist.length;
var excludedValues = this.options.excludedValues;
var found = false;
if (!optionsLength) { return; }
var option;
do {
option = shortlist[i];
if (option.text.toLowerCase().indexOf(value) === 0 && !excludedValues.contains(option.value)) {
found = true;
option.highlight(e);
typed.pressed = i + 1;
i = optionsLength;
}
i = i + 1;
} while(i < optionsLength);
return found;
},
highlightOption: function(option) {
if (this.highlighted) { this.highlighted.removeHighlight(); }
this.highlighted = option;
},
isOpen: function() {
return this.open;
},
keydown: function(e) {
if (!this.open) { return; }
this.dropdownOptions.each(function(option) { option.disable(); });
document.addEvent('mousemove', this.bound.mousemove);
},
keypress: function(e) {
if (!this.open) { return; }
(e).stop();
var code = e.code, key = e.key;
var typed = this.typed;
var match, i, options, option, optionsLength, found, first, excludedValues, shortlist;
switch(code) {
case 38: // up
case 37: // left
if (typed.pressed > 0) { typed.pressed = typed.pressed - 1; }
if (!this.highlighted) { this.dropdownOptions.getLast().highlight(e); break; }
match = this.highlighted.element.getPrevious();
match = match ? match.retrieve('Form.SelectOption::data') : this.dropdownOptions.getLast();
match.highlight(e);
break;
case 40: // down
case 39: // right
if (typed.shortlist.length > 0) { typed.pressed = typed.pressed + 1; }
if (!this.highlighted) { this.dropdownOptions[0].highlight(e); break; }
match = this.highlighted.element.getNext();
match = match ? match.retrieve('Form.SelectOption::data') : this.dropdownOptions[0];
match.highlight(e);
break;
case 13: // enter
e.stop();
case 9: // tab - skips the stop event but selects the item
this.highlighted.select();
break;
case 27: // esc
e.stop();
this.toggle();
break;
case 32: // space
default: // anything else
if (!(code >= 48 && code <= 122 && (code <= 57 || (code >= 65 && code <= 90) || code >=97) || code === 32)) {
break;
}
if (evt.control || evt.alt || evt.meta) { return; }
// alphanumeric or space
key = code === 32 ? ' ' : key;
clearTimeout(typed.timer);
options = this.dropdownOptions;
optionsLength = options.length;
excludedValues = this.options.excludedValues;
if (typed.timer === null) { // timer is expired
typed.shortlist = [];
if (key === typed.lastKey || key === typed.startkey) { // get next
typed.pressed = typed.pressed + 1;
typed.value = key;
} else { // get first
typed = this.resetTyped();
typed.value = key;
typed.startkey = key;
typed.pressed = 1;
}
typed.timer = this.resetTyped.delay(500, this);
} else {
if (key === typed.lastKey) { // check for match, if no match get next
typed.value = typed.value + key;
if (this.foundMatch(e)) { // got a match so break
typed.timer = this.resetTyped.delay(500, this);
break;
} else { // no match fall through
typed.shortlist = [];
typed.value = key;
typed.pressed = typed.pressed + 1;
typed.timer = null;
}
} else { // reset timer, get first match, set pressed to found position
typed.timer = this.resetTyped.delay(500, this);
typed.value = typed.value + key;
typed.startkey = typed.value.substring(0, 1);
typed.lastKey = key;
this.foundMatch(e);
break;
}
}
typed.lastKey = key;
shortlist = typed.shortlist;
i = 0;
found = 0;
do {
option = options[i];
if (option.text.toLowerCase().indexOf(key) === 0 && !excludedValues.contains(option.value)) {
if (found === 0) { first = option; }
found = found + 1;
if (found === typed.pressed) { option.highlight(e); }
shortlist.push(option);
}
i = i + 1;
} while(i < optionsLength);
if (typed.pressed > found) {
first.highlight(e);
typed.pressed = 1;
}
break;
}
},
mouseenterDropdown: function() {
clearTimeout(this.collapseInterval);
},
mouseleaveDropdown: function() {
this.collapseInterval = this.options.mouseLeaveDelay ? this.collapse.delay(this.options.mouseLeaveDelay,this) : null;
},
mousemove: function() {
this.dropdownOptions.each(function(option) { option.enable(); });
document.removeEvent('mousemove', this.bound.mousemove);
},
removeHighlightOption: function(option) {
this.highlighted = null;
},
reset: function() {
if (this.options.initialValue) {
this.dropdownOptions.each(function(o) {
if (o.value === this.options.initialValue) { o.select(); }
}, this);
} else {
this.dropdownOptions[0].select();
}
},
resetTyped: function() {
var typed = this.typed;
typed.value = null;
typed.timer = null;
return typed;
},
select: function(option, e) {
this.dropdownOptions.each(this.deselect);
this.selection.set('html', option.element.get('html'));
var oldValue = this.value;
this.value = option.value;
this.input.set('value', option.value);
this.selected = option;
this.fireEvent('select', [this, e]);
if (oldValue && oldValue !== this.value) { this.fireEvent('change', [this, e]); }
this.collapse(e);
},
toggle: function(e) {
if (this.open) { this.collapse(e); }
else { this.expand(e); }
},
updateOptions: function(optionElements) {
var optionsList = this.element.getElement('ul').empty(),
dropdownOptions = this.dropdownOptions.empty(),
selectOptions = this.options.selectOptions;
optionElements.each(function(opt) {
var option = new Form.SelectOption(opt, selectOptions);
option.addEvents({
'onHighlight':this.bound.highlightOption,
'onRemoveHighlight':this.bound.removeHighlightOption,
'onSelect':this.bound.select
}).owner = this;
if (option.value === this.options.initialValue || opt.get('selected')) { this.select(option); }
dropdownOptions.push(option);
optionsList.adopt(option.element);
}, this);
if (!this.selected && optionElements[0]) { optionElements[0].retrieve('Form.SelectOption::data').select(); }
}
});
@@ -0,0 +1,34 @@
/*
---
name: Form.Radio
description: Class to represent a radio button
authors: Bryan J Swift (@bryanjswift)
license: MIT-style license.
requires: [Core/Class.Extras, Core/Element, Core/Element.Event, Form-Replacement/Form.Check]
provides: Form.Radio
...
*/
if (typeof window.Form === 'undefined') { window.Form = {}; }
Form.Radio = new Class({
Extends: Form.Check,
config: {
elementClass: 'radio',
storage: 'Form.Radio::data'
},
initialize: function(input,options) {
this.parent(input,options);
},
toggle: function(e) {
if (this.element.hasClass('checked') || this.disabled) { return; }
var evt;
if (e) { evt = new Event(e).stop(); }
if (this.checked) {
this.uncheck();
} else {
this.check();
}
this.fireEvent(this.checked ? 'onCheck' : 'onUncheck',this);
this.fireEvent('onChange',this);
}
});
@@ -0,0 +1,93 @@
/*
---
name: Form.SelectOption
description: Class to represent an option for Form.Dropdown
authors: Bryan J Swift (@bryanjswift)
license: MIT-style license.
requires: [Core/Class.Extras, Core/Element, Core/Element.Event]
provides: Form.SelectOption
...
*/
if (typeof window.Form === 'undefined') { window.Form = {}; }
Form.SelectOption = new Class({
Implements: [Events, Options],
options: {
optionTag: 'li',
selected: false
},
config: {
highlightedClass: 'highlighted',
optionClass: 'option',
selectedClass: 'selected'
},
element: null,
bound: {},
option: null,
selected: false,
text: null,
value: null,
initialize: function(option, options) {
this.setOptions(options);
option = $(option);
this.option = option;
this.bound = {
deselect: this.deselect.bind(this),
highlight: this.highlight.bind(this),
removeHighlight: this.removeHighlight.bind(this),
select: this.select.bind(this)
};
this.text = option.get('text');
this.value = option.get('value');
this.element = new Element(this.options.optionTag, {
'class': (option.get('class') + ' ' + this.config.optionClass).trim(),
'html': option.get('html'),
'events': {
click: this.bound.select,
mouseenter: this.bound.highlight,
mouseleave: this.bound.removeHighlight
}
});
this.element.store('Form.SelectOption::data', this);
option.store('Form.SelectOption::data', this);
},
deselect: function(e) {
this.fireEvent('onDeselect', [this, e]);
this.element.removeClass(this.config.selectedClass).addEvent('click', this.bound.select);
this.selected = false;
},
destroy: function() {
this.element = null;
this.bound = null;
this.option = null;
},
disable: function() {
this.element.removeEvents({
mouseenter: this.bound.highlight,
mouseleave: this.bound.removeHighlight
});
this.fireEvent('onDisable', this);
},
enable: function() {
this.element.addEvents({
mouseenter: this.bound.highlight,
mouseleave: this.bound.removeHighlight
});
this.fireEvent('onEnable', this);
},
highlight: function(e) {
this.fireEvent('onHighlight', [this, e]);
this.element.addClass(this.config.highlightedClass);
return this;
},
removeHighlight: function(e) {
this.fireEvent('onRemoveHighlight', [this, e]);
this.element.removeClass(this.config.highlightedClass);
return this;
},
select: function(e) {
this.fireEvent('onSelect', [this, e]);
this.element.addClass(this.config.selectedClass).removeEvent('click', this.bound.select);
this.selected = true;
}
});
+20 -2
View File
@@ -3,6 +3,24 @@ Page.Manage = new Class({
Extends: PageBase,
name: 'manage',
title: 'Do stuff to your existing movies!'
title: 'Do stuff to your existing movies!',
indexAction: function(param){
var self = this;
self.list = new MovieList({
'status': 'done',
'actions': Manage.Action
});
$(self.list).inject(self.el);
}
});
var Manage = {
'Action': {
'IMBD': IMDBAction
}
}
})
+44 -18
View File
@@ -95,7 +95,7 @@ Page.Settings = new Class({
new Element('span', {
'text': 'Show advanced settings'
}),
self.advanced_toggle = new Element('input[type=checkbox]', {
self.advanced_toggle = new Element('input[type=checkbox].inlay', {
'events': {
'change': self.showAdvanced.bind(self)
}
@@ -103,6 +103,10 @@ Page.Settings = new Class({
)
)
);
new Form.Check(self.advanced_toggle, {
'onChange': self.showAdvanced.bind(self)
})
// Create tabs
Object.each(self.tabs, function(tab, tab_name){
@@ -132,8 +136,6 @@ Page.Settings = new Class({
});
});
self.fireEvent('create');
self.openTab();
@@ -150,7 +152,7 @@ Page.Settings = new Class({
new Element('a', {
'href': '/'+self.name+'/'+tab_name+'/',
'text': label
})
}).adopt()
).inject(self.tabs_container);
if(!self.tabs[tab_name])
@@ -335,7 +337,7 @@ Option.String = new Class({
self.el.adopt(
self.createLabel(),
self.input = new Element('input', {
self.input = new Element('input.inlay', {
'type': 'text',
'name': self.postName(),
'value': self.getSettingValue()
@@ -365,6 +367,11 @@ Option.Dropdown = new Class({
})
self.input.set('value', self.getSettingValue());
var dd = new Form.Dropdown(self.input, {
'onChange': self.changed.bind(self)
});
self.input = dd.input;
}
});
@@ -380,13 +387,17 @@ Option.Checkbox = new Class({
self.el.adopt(
self.createLabel().set('for', randomId),
self.input = new Element('input', {
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)
});
},
@@ -419,7 +430,7 @@ Option.Enabler = new Class({
var self = this;
self.el.adopt(
self.input = new Element('input', {
self.input = new Element('input.inlay', {
'type': 'checkbox',
'checked': self.getSettingValue(),
'id': 'r-'+randomString(),
@@ -427,7 +438,16 @@ Option.Enabler = new Class({
'change': self.checkState.bind(self)
}
})
)
);
new Form.Check(self.input, {
'onChange': self.changed.bind(self)
});
},
changed: function(){
this.parent();
this.checkState();
},
checkState: function(){
@@ -457,14 +477,13 @@ Option.Directory = new Class({
type: 'span',
browser: '',
save_on_change: false,
show_hidden: false,
create: function(){
var self = this;
self.el.adopt(
self.createLabel(),
self.input = new Element('span', {
self.input = new Element('span.directory', {
'text': self.getSettingValue(),
'events': {
'click': self.showBrowser.bind(self)
@@ -495,12 +514,19 @@ Option.Directory = new Class({
if(!self.browser)
self.browser = new Element('div.directory_list').adopt(
self.back_button = new Element('a.button.back', {
'text': '',
'events': {
'click': self.previousDirectory.bind(self)
}
}),
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)
@@ -584,7 +610,7 @@ Option.Directory = new Class({
Api.request('directory.list', {
'data': {
'path': c,
'show_hidden': +self.show_hidden
'show_hidden': +self.show_hidden.checked
},
'onComplete': self.fillBrowser.bind(self)
})
+41 -226
View File
@@ -5,208 +5,26 @@ Page.Wanted = new Class({
name: 'wanted',
title: 'Gimmy gimmy gimmy!',
movies: [],
indexAction: function(param){
var self = this;
self.get()
},
list: function(){
var self = this;
if(!self.movie_container)
self.movie_container = new Element('div.movies').inject(self.el);
self.movie_container.empty();
Object.each(self.movies, function(info){
var m = new Movie(self, {}, info);
$(m).inject(self.movie_container);
m.fireEvent('injected');
self.list = new MovieList({
'status': 'active',
'actions': Wanted.Action
});
$(self.list).inject(self.el);
self.movie_container.addEvents({
'mouseenter:relay(.movie)': function(e, el){
el.addClass('hover')
},
'mouseleave:relay(.movie)': function(e, el){
el.removeClass('hover')
}
})
},
get: function(status, onComplete){
var self = this
if(self.movies.length == 0)
Api.request('movie.list', {
'data': {},
'onComplete': function(json){
self.store(json.movies);
self.list();
}
})
else
self.list()
},
store: function(movies){
var self = this;
self.movies = movies;
}
});
var Movie = new Class({
Extends: BlockBase,
initialize: function(self, options, data){
var self = this;
self.data = data;
self.profile = Quality.getProfile(data.profile_id);
self.parent(self, options);
self.addEvent('injected', self.afterInject.bind(self))
},
create: function(){
var self = this;
self.el = new Element('div.movie').adopt(
self.data_container = new Element('div.data', {
'tween': {
duration: 400,
transition: 'quint:in:out'
}
}).adopt(
self.thumbnail = File.Select.single('poster', self.data.library.files),
self.info_container = new Element('div.info').adopt(
self.title = new Element('div.title', {
'text': self.getTitle()
}),
self.year = new Element('div.year', {
'text': self.data.library.year || 'Unknown'
}),
self.rating = new Element('div.rating', {
'text': self.data.library.rating
}),
self.description = new Element('div.description', {
'text': self.data.library.plot
}),
self.quality = new Element('div.quality', {
'text': self.profile.get('label')
})
),
self.actions = new Element('div.actions').adopt(
self.action_imdb = new Movie.Action.IMDB(self),
self.action_edit = new Movie.Action.Edit(self),
self.action_refresh = new Movie.Action.Refresh(self),
self.action_delete = new Movie.Action.Delete(self)
)
)
);
if(!self.data.library.rating)
self.rating.hide();
},
afterInject: function(){
var self = this;
var height = self.getHeight();
self.el.setStyle('height', height);
},
getTitle: function(){
var self = this;
var titles = self.data.library.titles;
var title = titles.filter(function(title){
return title['default']
}).pop()
if(title)
return title.title
else if(titles.length > 0)
return titles[0].title
return 'Unknown movie'
},
slide: function(direction){
var self = this;
if(direction == 'in'){
self.el.addEvent('outerClick', self.slide.bind(self, 'out'))
self.data_container.tween('left', 0, self.getWidth());
}
else {
self.el.removeEvents('outerClick')
self.data_container.tween('left', self.getWidth(), 0);
}
},
getHeight: function(){
var self = this;
if(!self.height)
self.height = self.data_container.getCoordinates().height;
return self.height;
},
getWidth: function(){
var self = this;
if(!self.width)
self.width = self.data_container.getCoordinates().width;
return self.width;
},
get: function(attr){
return this.data[attr] || this.data.library[attr]
var Wanted = {
'Action': {
'IMBD': IMDBAction
}
}
});
var MovieAction = new Class({
class_name: 'action',
initialize: function(movie){
var self = this;
self.movie = movie;
self.create();
self.el.addClass(self.class_name)
},
create: function(){},
disable: function(){
this.el.addClass('disable')
},
enable: function(){
this.el.removeClass('disable')
},
toElement: function(){
return this.el
}
})
Movie.Action = {}
Movie.Action.Edit = new Class({
Wanted.Action.Edit = new Class({
Extends: MovieAction,
@@ -229,7 +47,11 @@ Movie.Action.Edit = new Class({
if(!self.options_container){
self.options_container = new Element('div.options').adopt(
$(self.movie.thumbnail).clone(),
new Element('div.form').adopt(
new Element('div.form', {
'styles': {
'line-height': self.movie.getHeight()
}
}).adopt(
self.title_select = new Element('select', {
'name': 'title'
}),
@@ -244,56 +66,49 @@ Movie.Action.Edit = new Class({
})
)
).inject(self.movie, 'top');
}
Array.each(self.movie.data.library.titles, function(alt){
new Element('option', {
'text': alt.title
}).inject(self.title_select)
});
Object.each(Quality.profiles, function(profile){
new Element('option', {
'value': profile.id ? profile.id : profile.data.id,
'text': profile.label ? profile.label : profile.data.label
}).inject(self.profile_select);
self.profile_select.set('value', self.movie.profile.get('id'));
});
}
self.movie.slide('in');
},
save: function(){
save: function(e){
(e).stop();
var self = this;
Api.request('movie.edit', {
'data': {
'id': self.movie.get('id'),
'default_title': self.title_select.get('value'),
'profile_id': self.profile_select.get('value')
},
'useSpinner': true,
'spinnerTarget': self.movie
})
}
})
Movie.Action.IMDB = new Class({
Extends: MovieAction,
id: null,
create: function(){
var self = this;
self.id = self.movie.get('identifier');
self.el = new Element('a.imdb', {
'title': 'Go to the IMDB page of ' + self.movie.getTitle(),
'events': {
'click': self.gotoIMDB.bind(self)
'spinnerTarget': $(self.movie),
'onComplete': function(){
self.movie.quality.set('text', self.profile_select.getSelected()[0].get('text'))
self.movie.title.set('text', self.title_select.getSelected()[0].get('text'))
}
});
if(!self.id) self.disable();
},
gotoIMDB: function(e){
var self = this;
(e).stop();
window.open('http://www.imdb.com/title/'+self.id+'/');
self.movie.slide('out');
}
})
Movie.Action.Refresh = new Class({
Wanted.Action.Refresh = new Class({
Extends: MovieAction,
@@ -322,7 +137,7 @@ Movie.Action.Refresh = new Class({
})
Movie.Action.Delete = new Class({
Wanted.Action.Delete = new Class({
Extends: MovieAction,
@@ -360,7 +175,7 @@ Movie.Action.Delete = new Class({
'text': 'or'
}),
new Element('a.button.delete', {
'text': 'Delete movie',
'text': 'Delete ' + self.movie.title.get('text'),
'events': {
'click': self.del.bind(self)
}
@@ -411,4 +226,4 @@ Movie.Action.Delete = new Class({
}
})
})
+152 -11
View File
@@ -1,17 +1,18 @@
/* @override http://localhost:5000/static/style/main.css */
html {
color: #343434;
color: #fff;
font-size: 12px;
line-height: 1.5;
font-family: Helvetica, Arial, Geneva, sans-serif;
font-family: "Helvetica Neue", Helvetica, Arial, Geneva, sans-serif;
height: 100%;
text-shadow: 0 1px 0 #000;
}
body {
margin: 0;
padding: 0;
background: #fff;
background: #4e5969;
overflow-y: scroll;
height: 100%;
}
@@ -40,11 +41,11 @@ a img {
a {
text-decoration:none;
color: #6ea1d7;
color: #fff;
outline: 0;
cursor: pointer;
}
a:hover { color: #4d66c4; }
a:hover { color: #f3f3f3; }
.page {
display: none;
@@ -99,7 +100,7 @@ form {
}
.spinner{
background: #f7f7f7 url('../images/spinner.gif') no-repeat center;
background: #4e5969 url('../images/spinner.gif') no-repeat center;
}
.button {
@@ -130,9 +131,8 @@ form {
/*** Navigation ***/
.header {
background: #f7f7f7;
background: #4e5969;
padding:10px;
border-bottom: 1px solid #f1f1f1;
height: 60px;
-moz-box-shadow: 0 0 30px rgba(0,0,0,0.1);
-webkit-box-shadow: 0 0 30px rgba(0,0,0,0.1);
@@ -153,7 +153,7 @@ form {
padding: 0;
}
.header .navigation li {
color: #8b8b8b;
color: #fff;
display: inline-block;
font-size:20px;
font-weight: bold;
@@ -183,10 +183,151 @@ form {
}
.header .navigation li a:link, .header .navigation li a:visited {
color: #2c2c2c;
color: #fff;
}
.header .navigation li a:hover, .header .navigation li a:active {
color: #8b8b8b;
color: #b1d8dc;
}
/*** Global Styles ***/
.check {
display: inline-block;
vertical-align: middle;
height: 16px;
width: 16px;
cursor: pointer;
}
.check.highlighted { background-color: #424c59; }
.check.checked {
background-image: url('../images/checks.png');
background-position: -2px 0;
}
.check input {
display: none !important;
}
.select {
cursor: pointer;
display: inline-block;
}
.select .selection {
display: inline-block;
padding: 0 30px 0 20px;
border-radius:30px;
-moz-border-radius: 30px;
-webkit-border-radius: 30px;
box-shadow: 0 1px 1px rgba(0,0,0,0.35), inset 0 1px 0px rgba(255,255,255,0.20);
-moz-box-shadow: 0 1px 1px rgba(0,0,0,0.35), inset 0 1px 0px rgba(255,255,255,0.20);
-webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.35), inset 0 1px 0px rgba(255,255,255,0.20);
background: url('../images/checks.png') no-repeat 94% -53px, -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0, #406db8),
color-stop(1, #5b9bd1)
);
background: url('../images/checks.png') no-repeat 94% -53px, -moz-linear-gradient(
center top,
#5b9bd1 0%,
#406db8 100%
);
}
.select .selection .selectionDisplay {
display: inline-block;
padding-right: 15px;
border-right: 1px solid rgba(0,0,0,0.2);
box-shadow: 1px 0 0 rgba(255,255,255,0.15);
-moz-box-shadow: 1px 0 0 rgba(255,255,255,0.15);
-webkit-box-shadow: 1px 0 0 rgba(255,255,255,0.15);
}
.select .menu {
clear: both;
overflow: hidden;
font-weight: bold;
}
.select .list {
display: none;
background: #282d34;
border: 1px solid #1f242b;
position: absolute;
margin: 28px 0 0 0;
box-shadow: 0 1px 2px rgba(0,0,0,0.4);
-moz-box-shadow: 0 1px 2px rgba(0,0,0,0.4);
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.4);
border-radius:3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
z-index: 3;
}
.select.active .list {
display: block;
}
.select .list ul {
display: block;
width: 100% !important;
}
.select .list li {
padding: 2px 33px 2px 20px;
display: block;
}
.select .list li.highlighted {
background: rgba(255,255,255,0.1);
}
.select input { display: none; }
.inlay {
color: #fff;
border: 0;
border-radius:3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
background: #282d34;
box-shadow: inset 0 1px 8px rgba(0,0,0,0.25), 0 1px 0px rgba(255,255,255,0.25);
-moz-box-shadow: inset 0 1px 8px rgba(0,0,0,0.25), 0 1px 0px rgba(255,255,255,0.25);
-webkit-box-shadow: inset 0 1px 8px rgba(0,0,0,0.25), 0 1px 0px rgba(255,255,255,0.25);
}
.inlay.light {
background: #47515f;
outline: none;
box-shadow: inset 0 1px 8px rgba(0,0,0,0.05), 0 1px 0px rgba(255,255,255,0.15);
-moz-box-shadow: inset 0 1px 8px rgba(0,0,0,0.05), 0 1px 0px rgba(255,255,255,0.15);
-webkit-box-shadow: inset 0 1px 8px rgba(0,0,0,0.05), 0 1px 0px rgba(255,255,255,0.15);
}
.inlay:focus {
background: #3a4350;
outline: none;
}
.onlay, .inlay .selected, .inlay > li:hover {
border-radius:3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border: 1px solid #252930;
box-shadow: inset 0 1px 0px rgba(255,255,255,0.20), 0 0 3px rgba(0,0,0, 0.2);
-moz-box-shadow: inset 0 1px 0px rgba(255,255,255,0.20), 0 0 3px rgba(0,0,0, 0.2);
-webkit-box-shadow: inset 0 1px 0px rgba(255,255,255,0.20), 0 0 3px rgba(0,0,0, 0.2);
background-image: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0, rgb(55,62,74)),
color-stop(1, rgb(73,83,98))
);
background-image: -moz-linear-gradient(
center bottom,
rgb(55,62,74) 0%,
rgb(73,83,98) 100%
);
}
+88 -24
View File
@@ -12,35 +12,40 @@
list-style: none;
padding: 40px 0;
margin: 0;
min-height: 300px;
min-height: 470px;
background-image: -webkit-gradient(
linear,
right top,
40% 4%,
color-stop(0, rgba(0,0,0, 0.3)),
color-stop(0.9, rgba(0,0,0, 0))
);
background-image: -moz-linear-gradient(
30% 0% 16deg,
rgba(0,0,0,0) 0%,
rgba(0,0,0,0.3) 100%
);
}
.page.settings .tabs a {
display: block;
padding: 10px 15px;
border: 1px solid transparent;
position: relative;
z-index: 1;
margin-right: -1px;
padding: 11px 15px;
}
.page.settings .tabs .active a {
color: black;
background: #fbfbfb;
border-color: #f1f1f1;
border-right-color: transparent;
background: #4e5969;
}
.page.settings .containers {
width: 75.8%;
float: left;
padding: 20px 2%;
min-height: 300px;
background: #fbfbfb;
border-left: 1px solid #f1f1f1;s
}
.page.settings .advanced {
display: none;
color: #ce3b19;
color: #edc07f;
}
.page.settings.show_advanced .advanced { display: block; }
@@ -57,10 +62,13 @@
font-size: 25px;
padding: 0 9px 10px 30px;
margin: 0;
border-bottom: 1px solid #f3f3f3;
border-bottom: 1px solid #333;
box-shadow: 0 1px 0px rgba(255,255,255, 0.15);
-moz-box-shadow: 0 1px 0px rgba(255,255,255, 0.15);
-webkit-box-shadow: 0 1px 0px rgba(255,255,255, 0.15);
}
.page.settings fieldset h2 .hint {
color: #888;
font-size: 12px;
margin-left: 10px;
}
@@ -81,26 +89,44 @@
.page.settings .ctrlHolder {
line-height: 25px;
padding: 10px 10px 10px 30px;
border-bottom: 1px solid #f3f3f3;
font-size: 14px;
border: 0;
}
.page.settings .ctrlHolder:last-child { border: none; }
.page.settings .ctrlHolder:hover { background: rgba(211,234,254,0.1); }
.page.settings .ctrlHolder.focused:hover { background: rgba(251,246,48,0.29); }
.page.settings .ctrlHolder:hover { background: rgba(255,255,255,0.05); }
.page.settings .ctrlHolder.focused { background: rgba(255,255,255,0.2); }
.page.settings .ctrlHolder .formHint {
float: right;
width: 47%;
margin: -18px 0;
padding: 0;
color: #fff;
}
.check {
display: inline-block;
vertical-align: middle;
height: 16px;
width: 16px;
cursor: pointer;
}
.check.highlighted { background-color: #424c59; }
.check.checked {
background-image: url('../../images/checks.png');
background-position: -2px 0;
}
.check input {
display: none;
}
.page.settings .ctrlHolder input[type=checkbox] + .formHint {
.page.settings .check + .formHint {
float: none;
width: auto;
display: inline-block;
margin-left: 1% !important;
color: #222;
height: 24px;
vertical-align: middle;
}
.page.settings .ctrlHolder label {
@@ -111,8 +137,7 @@
}
.page.settings input[type=text], .page.settings input[type=password] {
border: 1px solid #aaa;
padding: 3px;
padding: 5px 3px;
margin: 0;
width: 30%;
@@ -135,5 +160,44 @@
}
.page.settings .advanced_toggle span { padding: 0 5px; }
.page.settings.show_advanced .advanced_toggle {
color: #ce3b19;
}
color: #edc07f;
}
.page.settings .directory {
display: inline-block;
padding: 0 4px;
font-size: 13px;
width: 29.7%;
}
.page.settings .directory_list {
position: absolute;
width: 300px;
margin: 0 0 0 16.5%;
background: #282d34;
border: 1px solid #1f242b;
position: absolute;
box-shadow: 0 1px 2px rgba(0,0,0,0.4);
-moz-box-shadow: 0 1px 2px rgba(0,0,0,0.4);
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.4);
border-radius:3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
.page.settings .directory_list ul {
width: 100%;
max-height: 200px;
overflow: auto;
}
.page.settings .directory_list li {
padding: 2px 10px;
}
.page.settings .directory_list .actions {
clear: both;
padding: 10px;
background: #414953;
}
.page.settings .directory_list .actions:first-child { border-bottom: 1px solid #1f242b; }
.page.settings .directory_list .actions:last-child { border-top: 1px solid #1f242b; }
-134
View File
@@ -1,134 +0,0 @@
/* @override http://localhost:5000/static/style/page/wanted.css */
.page.wanted .movies {
padding: 20px 0;
}
.page.wanted .movie {
overflow: hidden;
position: relative;
background: #999;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
margin: 10px 0;
border: 1px solid #fff;
border-color: #eee #fff #fff #eee;
background: #ddd;
}
.page.wanted .movie:hover {
border-color: #ddd #fff #fff #ddd;
}
.page.wanted .movie:hover .data {
background: #f5f5f5;
}
.page.wanted .data {
padding: 2%;
position: absolute;
width: 96.1%;
top: 0;
left: 0;
background: #f9f9f9;
}
.page.wanted .data:after {
content: "";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.page.wanted .data .poster, .page.wanted .options .poster {
overflow: hidden;
float: left;
max-width: 10%;
margin: 0 2% 0 0;
border-radius:3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
-moz-box-shadow: 0 0 10px rgba(0,0,0,0.35);
-webkit-box-shadow: 0 0 10px rgba(0,0,0,0.35);
line-height: 0;
}
.page.wanted .info {
float: right;
width: 88%;
}
.page.wanted .info .title {
font-size: 30px;
font-weight: bold;
margin-bottom: 10px;
float: left;
width: 80%;
}
.page.wanted .info .year {
font-size: 30px;
margin-bottom: 10px;
float: right;
color: #bbb;
width: 10%;
text-align: right;
}
.page.wanted .info .rating {
font-size: 30px;
margin-bottom: 10px;
color: #444;
float: left;
width: 5%;
padding: 0 0 0 3%;
background: url('../../images/rating.png') no-repeat left center;
}
.page.wanted .info .description {
clear: both;
width: 95%;
}
.page.wanted .data .actions {
position: absolute;
right: 15px;
bottom: 15px;
line-height: 0;
}
.page.wanted .data:hover .action { opacity: 0.6; }
.page.wanted .data:hover .action:hover { opacity: 1; }
.page.wanted .data .action {
background: no-repeat center;
display: inline-block;
width: 20px;
height: 20px;
padding: 3px;
opacity: 0;
}
.page.wanted .data .action.refresh { background-image: url('../../images/reload.png'); }
.page.wanted .data .action.delete { background-image: url('../../images/delete.png'); }
.page.wanted .data .action.edit { background-image: url('../../images/edit.png'); }
.page.wanted .data .action.imdb { background-image: url('../../images/imdb.png'); }
.page.wanted .delete_container {
clear: both;
text-align: center;
font-size: 20px;
position: relative;
}
.page.wanted .delete_container .cancel {
}
.page.wanted .delete_container .or {
padding: 10px;
}
.page.wanted .delete_container .delete {
background-color: #ff321c;
font-weight: normal;
}
.page.wanted .delete_container .delete:hover {
color: #fff;
background-color: #d32917;
}
.page.wanted .options {
padding: 2%;
}