forked from 0x2620/pandora
split up pandora.js
This commit is contained in:
parent
1e985ebf63
commit
88a976b12d
41 changed files with 4508 additions and 3931 deletions
3900
static/js/pandora.js
Executable file → Normal file
3900
static/js/pandora.js
Executable file → Normal file
File diff suppressed because it is too large
Load diff
160
static/js/pandora/Query.js
Normal file
160
static/js/pandora/Query.js
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.Query = (function() {
|
||||||
|
|
||||||
|
function constructFind(query) {
|
||||||
|
//Ox.print('cF', query)
|
||||||
|
return /*encodeURI(*/$.map(query.conditions, function(v, i) {
|
||||||
|
if (!Ox.isUndefined(v.conditions)) {
|
||||||
|
return '[' + constructFind(v) + ']';
|
||||||
|
} else {
|
||||||
|
return v.value !== '' ? v.key + (v.key ? ':' : '') + constructValue(v.value, v.operator) : null;
|
||||||
|
}
|
||||||
|
}).join(query.operator)/*)*/;
|
||||||
|
}
|
||||||
|
|
||||||
|
function constructValue(value, operator) {
|
||||||
|
operator = operator.replace('=', '^$');
|
||||||
|
if (operator.indexOf('$') > -1) {
|
||||||
|
value = operator.substr(0, operator.length - 1) + value + '$';
|
||||||
|
} else {
|
||||||
|
value = operator + value;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mergeFind() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseFind(str) {
|
||||||
|
str = str || '';
|
||||||
|
var find = {
|
||||||
|
conditions: [],
|
||||||
|
operator: ''
|
||||||
|
},
|
||||||
|
subconditions = str.match(/\[.*?\]/g) || [];
|
||||||
|
$.each(subconditions, function(i, v) {
|
||||||
|
subconditions[i] = v.substr(1, v.length - 2);
|
||||||
|
str = str.replace(v, '[' + i + ']');
|
||||||
|
});
|
||||||
|
if (str.indexOf(',') > -1) {
|
||||||
|
find.operator = '&';
|
||||||
|
} else if (str.indexOf('|') > -1) {
|
||||||
|
find.operator = '|';
|
||||||
|
}
|
||||||
|
//Ox.print('pF', str, find.operator)
|
||||||
|
find.conditions = $.map(find.operator === '' ? [str] : str.split(find.operator == '&' ? ',' : '|'), function(v, i) {
|
||||||
|
//Ox.print('v', v)
|
||||||
|
var ret, kv;
|
||||||
|
if (v[0] == '[') {
|
||||||
|
//Ox.print('recursion', subconditions)
|
||||||
|
ret = parseFind(subconditions[parseInt(v.substr(1, v.length - 2))]);
|
||||||
|
} else {
|
||||||
|
kv = ((v.indexOf(':') > - 1 ? '' : ':') + v).split(':');
|
||||||
|
if (kv[0] == 'list') { // fixme: this is just a hack
|
||||||
|
app.user.ui.listQuery = {conditions: [$.extend({
|
||||||
|
key: kv[0]
|
||||||
|
}, parseValue(kv[1]))], operator: ''};
|
||||||
|
} else {
|
||||||
|
ret = $.extend({
|
||||||
|
key: kv[0]
|
||||||
|
}, parseValue(kv[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
return find;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseValue(str) {
|
||||||
|
var value = {
|
||||||
|
value: decodeURI(str),
|
||||||
|
operator: ''
|
||||||
|
};
|
||||||
|
if (value.value[0] == '!') {
|
||||||
|
value.operator = '!';
|
||||||
|
value.value = value.value.substr(1);
|
||||||
|
}
|
||||||
|
if ('^<>'.indexOf(value.value[0]) > -1) {
|
||||||
|
value.operator += value.value[0];
|
||||||
|
value.value = value.value.substr(1);
|
||||||
|
}
|
||||||
|
if (value.value.substr(-1) == '$') {
|
||||||
|
value.operator += '$';
|
||||||
|
value.value = value.value.substr(0, value.value.length - 1);
|
||||||
|
}
|
||||||
|
value.operator = value.operator.replace('^$', '=');
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
fromString: function(str) {
|
||||||
|
var list = '',
|
||||||
|
query = Ox.unserialize(str.substr(1)),
|
||||||
|
sort = [];
|
||||||
|
if ('find' in query) {
|
||||||
|
app.user.ui.listQuery = {conditions: [], operator: ''}; // fixme: hackish
|
||||||
|
app.user.ui.findQuery = parseFind(query.find);
|
||||||
|
if (app.user.ui.listQuery.conditions.length) {
|
||||||
|
list = app.user.ui.listQuery.conditions[0].value;
|
||||||
|
!app.user.ui.lists[list] && pandora.UI.set(
|
||||||
|
['lists', list].join('|'), app.config.user.ui.lists['']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pandora.UI.set({list: list});
|
||||||
|
//Ox.print('user.ui.findQuery', app.user.ui.findQuery)
|
||||||
|
}
|
||||||
|
if ('sort' in query) {
|
||||||
|
sort = query.sort.split(',');
|
||||||
|
pandora.UI.set(['lists', app.user.ui.list, 'sort'].join('|'), $.map(query.sort.split(','), function(v, i) {
|
||||||
|
var hasOperator = '+-'.indexOf(v[0]) > -1,
|
||||||
|
key = hasOperator ? query.sort.substr(1) : query.sort,
|
||||||
|
operator = hasOperator ? v[0]/*.replace('+', '')*/ : pandora.getSortOperator(key);
|
||||||
|
return {
|
||||||
|
key: key,
|
||||||
|
operator: operator
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
if ('view' in query) {
|
||||||
|
pandora.UI.set(['lists', app.user.ui.list, 'listView'].join('|'), query.view);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toObject: function(groupId) {
|
||||||
|
//Ox.print('tO', app.user.ui.findQuery.conditions)
|
||||||
|
// the inner $.merge() creates a clone
|
||||||
|
var conditions = $.merge(
|
||||||
|
$.merge([], app.user.ui.listQuery.conditions),
|
||||||
|
app.user.ui.findQuery.conditions
|
||||||
|
),
|
||||||
|
operator;
|
||||||
|
$.merge(conditions, app.ui.groups ? $.map(app.ui.groups, function(v, i) {
|
||||||
|
if (v.id != groupId && v.query.conditions.length) {
|
||||||
|
return v.query.conditions.length == 1 ?
|
||||||
|
v.query.conditions : v.query;
|
||||||
|
}
|
||||||
|
}) : []);
|
||||||
|
operator = conditions.length < 2 ? '' : ','; // fixme: should be &
|
||||||
|
//Ox.print('>>', groupId, app.user.ui.find, conditions);
|
||||||
|
return {
|
||||||
|
conditions: conditions,
|
||||||
|
operator: operator
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
toString: function() {
|
||||||
|
//Ox.print('tS', app.user.ui.find)
|
||||||
|
var sort = app.user.ui.lists[app.user.ui.list].sort[0],
|
||||||
|
key = sort.key,
|
||||||
|
operator = sort.operator;
|
||||||
|
return '?' + Ox.serialize({
|
||||||
|
find: constructFind(pandora.Query.toObject()),
|
||||||
|
sort: (operator == pandora.getSortOperator(key) ? '' : operator) + key,
|
||||||
|
view: app.user.ui.lists[app.user.ui.list].listView
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
31
static/js/pandora/UI.js
Normal file
31
static/js/pandora/UI.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.UI = (function() {
|
||||||
|
return {
|
||||||
|
set: function(obj) {
|
||||||
|
if (arguments.length == 2) {
|
||||||
|
// translate (key, value) to {key: value}
|
||||||
|
var obj_ = {};
|
||||||
|
obj_[arguments[0]] = arguments[1];
|
||||||
|
obj = obj_;
|
||||||
|
}
|
||||||
|
$.each(obj, function(key, val) {
|
||||||
|
Ox.print('key', key, 'val', val);
|
||||||
|
var i = 0,
|
||||||
|
keys = key.split('|'),
|
||||||
|
old = app.user.ui;
|
||||||
|
while (i < keys.length - 1) {
|
||||||
|
old = old[keys[i]];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (old[keys[i]] !== val) {
|
||||||
|
old[keys[i]] = val;
|
||||||
|
} else {
|
||||||
|
delete obj[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ox.len(obj) && pandora.api.setUI(obj);
|
||||||
|
//alert('set ' + JSON.stringify(obj))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
|
126
static/js/pandora/URL.js
Normal file
126
static/js/pandora/URL.js
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.URL = (function() {
|
||||||
|
|
||||||
|
var old = {
|
||||||
|
user: {
|
||||||
|
ui: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
regexps = {
|
||||||
|
'^\\?': function(url) {
|
||||||
|
pandora.Query.fromString(url);
|
||||||
|
pandora.UI.set({
|
||||||
|
section: 'items',
|
||||||
|
item: ''
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'^(|about|archives|faq|help|license|home|news|preferences|software|terms|tour)$': function(url) {
|
||||||
|
pandora.UI.set({
|
||||||
|
section: 'site',
|
||||||
|
sitePage: url || 'home'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'^admin': function(url) {
|
||||||
|
var split = url.split('/'),
|
||||||
|
section = new RegExp(
|
||||||
|
'^ˆ(statistics|users)$'
|
||||||
|
).exec(split[1]);
|
||||||
|
section = section ? section[0] : 'users';
|
||||||
|
pandora.UI.set({
|
||||||
|
section: 'site',
|
||||||
|
sitePage: url
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'^(find)$': function() {
|
||||||
|
pandora.Query.fromString('?find='); // fixme: silly hack
|
||||||
|
pandora.UI.set({
|
||||||
|
section: 'items',
|
||||||
|
item: ''
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'^(calendar|calendars|clips|icons|flow|map|maps|timelines)$': function() {
|
||||||
|
pandora.UI.set({
|
||||||
|
section: 'items',
|
||||||
|
item: ''
|
||||||
|
});
|
||||||
|
pandora.UI.set(['lists', app.user.ui.list, 'listView'].join('|'), url);
|
||||||
|
},
|
||||||
|
'^[0-9A-Z]': function(url) {
|
||||||
|
var split = url.split('/'),
|
||||||
|
item = split[0],
|
||||||
|
view = new RegExp(
|
||||||
|
'^(' + $.map(app.config.itemViews, function(v) {
|
||||||
|
return v.id
|
||||||
|
}).join('|') + ')$'
|
||||||
|
).exec(split[1]);
|
||||||
|
view = view ? view[0] : app.user.ui.itemView;
|
||||||
|
pandora.UI.set({
|
||||||
|
section: 'items',
|
||||||
|
item: item,
|
||||||
|
itemView: view
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'^texts$': function() {
|
||||||
|
pandora.UI.set({
|
||||||
|
section: 'texts'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
set: function(title, url) {
|
||||||
|
if (arguments.length == 1) { // fixme: remove later
|
||||||
|
url = title;
|
||||||
|
}
|
||||||
|
history.pushState({}, app.config.site.name + (title ? ' - ' + title : ''), '/' + url);
|
||||||
|
old.user.ui = $.extend({}, app.user.ui); // make a clone
|
||||||
|
this.update();
|
||||||
|
},
|
||||||
|
|
||||||
|
parse: function() {
|
||||||
|
var url = document.location.pathname.substr(1) +
|
||||||
|
document.location.search +
|
||||||
|
document.location.hash;
|
||||||
|
$.each(regexps, function(re, fn) {
|
||||||
|
//Ox.print(url, 're', re)
|
||||||
|
re = new RegExp(re);
|
||||||
|
if (re.test(url)) {
|
||||||
|
Ox.print('URL re ' + re);
|
||||||
|
fn(url);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
update: function() {
|
||||||
|
this.parse();
|
||||||
|
if (app.user.ui.section != old.user.ui.section) {
|
||||||
|
app.$ui.appPanel.replaceElement(1, app.$ui.mainPanel = pandora.ui.mainPanel());
|
||||||
|
} else if (app.user.ui.sitePage != old.user.ui.sitePage) {
|
||||||
|
app.$ui.mainPanel.replaceElement(1, app.$ui.rightPanel = pandora.ui.rightPanel());
|
||||||
|
} else if (!app.user.ui.item || !old.user.ui.item) {
|
||||||
|
app.$ui.mainPanel.replaceElement(1, app.$ui.rightPanel = pandora.ui.rightPanel());
|
||||||
|
app.$ui.leftPanel.replaceElement(2, app.$ui.info = pandora.ui.info());
|
||||||
|
} else {
|
||||||
|
app.$ui.contentPanel.replaceElement(1, pandora.ui.item());
|
||||||
|
app.$ui.leftPanel.replaceElement(2, app.$ui.info = pandora.ui.info());
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
old.user.ui.item &&
|
||||||
|
['player', 'timeline'].indexOf(old.user.ui.itemView) > -1
|
||||||
|
) {
|
||||||
|
pandora.UI.set(
|
||||||
|
'videoPosition|' + old.user.ui.item,
|
||||||
|
app.$ui[
|
||||||
|
old.user.ui.itemView == 'player' ? 'player' : 'editor'
|
||||||
|
].options('position')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
delete old.user.ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
75
static/js/pandora/autovalidate.js
Normal file
75
static/js/pandora/autovalidate.js
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.autovalidateCode = function(value, blur, callback) {
|
||||||
|
value = $.map(value.toUpperCase().split(''), function(v) {
|
||||||
|
return /[0-9A-Z]/(v) ? v : null;
|
||||||
|
}).join('');
|
||||||
|
callback(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
pandora.autovalidateEmail = function(value, blur, callback) {
|
||||||
|
value = $.map(value.toLowerCase().split(''), function(v, i) {
|
||||||
|
return /[0-9a-z\.\+\-_@]/(v) ? v : null;
|
||||||
|
}).join('');
|
||||||
|
callback(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
pandora.autovalidateListname = function(value, blur, callback) {
|
||||||
|
var length = value.length;
|
||||||
|
value = $.map(value.split(''), function(v, i) {
|
||||||
|
if (new RegExp('[0-9' + Ox.regexp.letters + '\\(\\)' + ((i == 0 || (i == length - 1 && blur)) ? '' : ' \-') + ']', 'i').test(v)) {
|
||||||
|
return v;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).join('');
|
||||||
|
$.each([' ', ' -', '- ', '--', '\\(\\(', '\\)\\(', '\\)\\)'], function(i, v) {
|
||||||
|
//Ox.print(v, v[0], v[0] == '\\')
|
||||||
|
while (value.indexOf(v) > -1) {
|
||||||
|
value = value.replace(new RegExp(v, 'g'), v[0] + (v[0] == '\\' ? v[1] : ''));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
callback(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
pandora.autovalidateUsername = function(value, blur, callback) {
|
||||||
|
var length = value.length;
|
||||||
|
value = $.map(value.toLowerCase().split(''), function(v, i) {
|
||||||
|
if (new RegExp('[0-9a-z' + ((i == 0 || (i == length - 1 && blur)) ? '' : '\-_') + ']').test(v)) {
|
||||||
|
return v;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).join('');
|
||||||
|
$.each(['--', '-_', '_-', '__'], function(i, v) {
|
||||||
|
while (value.indexOf(v) > -1) {
|
||||||
|
value = value.replace(new RegExp(v, 'g'), v[0]);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
callback(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
pandora.validateUser = function(key, existing) {
|
||||||
|
existing = existing || false;
|
||||||
|
var string = key == 'username' ? 'username' : 'e-mail address';
|
||||||
|
return function(value, callback) {
|
||||||
|
var valid = key == 'username' ? !!value.length : Ox.isValidEmail(value);
|
||||||
|
valid ? pandora.api.findUser({
|
||||||
|
key: key,
|
||||||
|
value: value,
|
||||||
|
operator: '='
|
||||||
|
}, function(result) {
|
||||||
|
var valid = existing == !!result.data.users.length;
|
||||||
|
//Ox.print(existing, result.data.users)
|
||||||
|
callback({
|
||||||
|
message: existing ?
|
||||||
|
'Unknown ' + string :
|
||||||
|
string[0].toUpperCase() + string.substr(1) + ' already exists',
|
||||||
|
valid: valid
|
||||||
|
});
|
||||||
|
}) : callback({
|
||||||
|
message: (!value.length ? 'Missing' : 'Invalid') + ' ' + string,
|
||||||
|
valid: false
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
213
static/js/pandora/pandora.js
Normal file
213
static/js/pandora/pandora.js
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.enterFullscreen = function() {
|
||||||
|
app.$ui.appPanel.size(0, 0);
|
||||||
|
app.user.ui.showSidebar && app.$ui.mainPanel.size(0, 0);
|
||||||
|
app.$ui.rightPanel.size(0, 0).size(2, 0);
|
||||||
|
!app.user.ui.showMovies && app.$ui.contentPanel.css({
|
||||||
|
top: (-112 - Ox.UI.SCROLLBAR_SIZE) + 'px' // fixme: rightPanel.size(0, 0) doesn't preserve negative top of browser
|
||||||
|
});
|
||||||
|
app.user.ui.showMovies && app.$ui.contentPanel.size(0, 0);
|
||||||
|
app.$ui.player.options({
|
||||||
|
height: app.$document.height() - 2,
|
||||||
|
width: app.$document.width() - 2
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.exitFullscreen = function() {
|
||||||
|
app.$ui.appPanel.size(0, 20);
|
||||||
|
app.user.ui.showSidebar && app.$ui.mainPanel.size(0, app.user.ui.sidebarSize);
|
||||||
|
app.$ui.rightPanel.size(0, 24).size(2, 16);
|
||||||
|
!app.user.ui.showMovies && app.$ui.contentPanel.css({
|
||||||
|
top: 24 + (-112 - Ox.UI.SCROLLBAR_SIZE) + 'px' // fixme: rightPanel.size(0, 0) doesn't preserve negative top of browser
|
||||||
|
});
|
||||||
|
app.user.ui.showMovies && app.$ui.contentPanel.size(0, 112 + Ox.UI.SCROLLBAR_SIZE);
|
||||||
|
}
|
||||||
|
pandora.getFoldersHeight = function() {
|
||||||
|
var height = 48;
|
||||||
|
app.ui.sectionFolders[app.user.ui.section].forEach(function(folder, i) {
|
||||||
|
height += app.user.ui.showFolder[app.user.ui.section][folder.id] * (
|
||||||
|
!!folder.showBrowser * 40 + folder.items * 16
|
||||||
|
);
|
||||||
|
Ox.print('h', height)
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
$.each(app.user.ui.showFolder[app.user.ui.section], function(id, show) {
|
||||||
|
var i = Ox.getPositionById(app.ui.sectionFolders[app.user.ui.section], id);
|
||||||
|
height += show * (
|
||||||
|
app.ui.sectionFolders[app.user.ui.section][i].showBrowser * 40 +
|
||||||
|
app.ui.sectionFolders[app.user.ui.section][i].items * 16
|
||||||
|
);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.getFoldersWidth = function() {
|
||||||
|
var width = app.user.ui.sidebarSize;
|
||||||
|
// fixme: don't use height(), look up in splitpanels
|
||||||
|
Ox.print(pandora.getFoldersHeight(), '>', app.$ui.leftPanel.height() - 24 - 1 - app.$ui.info.height())
|
||||||
|
if (pandora.getFoldersHeight() > app.$ui.leftPanel.height() - 24 - 1 - app.$ui.info.height()) {
|
||||||
|
width -= Ox.UI.SCROLLBAR_SIZE;
|
||||||
|
}
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.getGroupWidth = function(pos, panelWidth) { // fixme: don't pass panelWidth
|
||||||
|
var width = {};
|
||||||
|
width.list = Math.floor(panelWidth / 5) + (panelWidth % 5 > pos);
|
||||||
|
width.column = width.list - 40 - Ox.UI.SCROLLBAR_SIZE;
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.getSortOperator = function(key) { // fixme: make static
|
||||||
|
var type = Ox.getObjectById(app.config.itemKeys, key).type;
|
||||||
|
return ['hue', 'string', 'text'].indexOf(
|
||||||
|
Ox.isArray(type) ? type[0] : type
|
||||||
|
) > -1 ? '+' : '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.login = function(data) {
|
||||||
|
app.user = data.user;
|
||||||
|
Ox.Theme(app.user.ui.theme);
|
||||||
|
app.$ui.appPanel.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.logout = function(data) {
|
||||||
|
app.user = data.user;
|
||||||
|
Ox.Theme(app.config.user.ui.theme);
|
||||||
|
app.$ui.appPanel.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.reloadGroups = function(i) {
|
||||||
|
var query = pandora.Query.toObject();
|
||||||
|
app.$ui.list.options({
|
||||||
|
items: function(data, callback) {
|
||||||
|
return pandora.api.find($.extend(data, {
|
||||||
|
query: query
|
||||||
|
}), callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$.each(app.ui.groups, function(i_, group_) {
|
||||||
|
if (i_ != i) {
|
||||||
|
//Ox.print('setting groups request', i, i_)
|
||||||
|
app.$ui.groups[i_].options({
|
||||||
|
items: function(data, callback) {
|
||||||
|
delete data.keys;
|
||||||
|
return pandora.api.find($.extend(data, {
|
||||||
|
group: group_.id,
|
||||||
|
query: pandora.Query.toObject(group_.id)
|
||||||
|
}), callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
history.pushState({}, '', pandora.Query.toString(query));
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.getListData = function() {
|
||||||
|
var data = {};
|
||||||
|
if (app.user.ui.list) {
|
||||||
|
var folder = app.$ui.folderList['personal'].options('selected')[0] ==
|
||||||
|
app.user.ui.list ? 'personal' : 'featured';
|
||||||
|
data = app.$ui.folderList[folder].value(app.user.ui.list);
|
||||||
|
}
|
||||||
|
data.editable = data.user == app.user.username && data.type == 'static';
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.reloadList = function() {
|
||||||
|
Ox.print('reloadList')
|
||||||
|
var listData = pandora.getListData();
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
app.$ui.groups.forEach(function($group) {
|
||||||
|
$group.reloadList();
|
||||||
|
});
|
||||||
|
app.$ui.list.bindEvent({
|
||||||
|
init: function(event, data) {
|
||||||
|
app.$ui.folderList[listData.status]
|
||||||
|
.value(listData.id, 'items', data.items);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.bindEventOnce({
|
||||||
|
load: function(event, data) {
|
||||||
|
app.$ui.list.gainFocus().options({selected: [data.items]});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.reloadList();
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.resizeGroups = function(width) {
|
||||||
|
var widths = $.map(app.ui.groups, function(v, i) {
|
||||||
|
return pandora.getGroupWidth(i, width);
|
||||||
|
});
|
||||||
|
//Ox.print('widths', widths);
|
||||||
|
app.$ui.browser.size(0, widths[0].list).size(2, widths[4].list);
|
||||||
|
app.$ui.groupsInnerPanel.size(0, widths[1].list).size(2, widths[3].list);
|
||||||
|
$.each(app.$ui.groups, function(i, list) {
|
||||||
|
list.resizeColumn('name', widths[i].column);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.resizeFolders = function() {
|
||||||
|
var width = pandora.getFoldersWidth(),
|
||||||
|
columnWidth = {};
|
||||||
|
if (app.user.ui.section == 'site') {
|
||||||
|
columnWidth.title = width - 16;
|
||||||
|
} else if (app.user.ui.section == 'items') {
|
||||||
|
columnWidth = {user: parseInt((width - 88) * 0.4)};
|
||||||
|
columnWidth.name = (width - 88) - columnWidth.user;
|
||||||
|
}
|
||||||
|
//Ox.print('sectionsWidth', width)
|
||||||
|
$.each(app.$ui.folderList, function(id, $list) {
|
||||||
|
var i = Ox.getPositionById(app.ui.sectionFolders[app.user.ui.section], id);
|
||||||
|
app.$ui.folder[i].css({width: width + 'px'});
|
||||||
|
$list.css({width: width + 'px'});
|
||||||
|
Ox.print('...', id, $list.options())
|
||||||
|
if (app.user.ui.section == 'site') {
|
||||||
|
$list.resizeColumn('title', columnWidth.title);
|
||||||
|
} else if (app.user.ui.section == 'items') {
|
||||||
|
if (app.ui.sectionFolders[app.user.ui.section][i].showBrowser) {
|
||||||
|
$list.resizeColumn('user', columnWidth.user)
|
||||||
|
.resizeColumn('name', columnWidth.name);
|
||||||
|
} else {
|
||||||
|
$list.resizeColumn(id == 'favorite' ? 'id' : 'name', width - 88);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!app.user.ui.showFolder[app.user.ui.section][id]) {
|
||||||
|
app.$ui.folder[i].update();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.saveVideoPosition = function() {
|
||||||
|
//alert(JSON.stringify(['videoPosition|' + old.user.ui.item, app.$ui[old.user.ui.itemView == 'player' ? 'player' : 'editor'].options('position')]));
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora.selectList = function() {
|
||||||
|
if (app.user.ui.list) {
|
||||||
|
pandora.api.findLists({
|
||||||
|
keys: ['status', 'user'],
|
||||||
|
query: {
|
||||||
|
conditions: [{key: 'id', value: app.user.ui.list, operator: '='}],
|
||||||
|
operator: ''
|
||||||
|
},
|
||||||
|
range: [0, 1]
|
||||||
|
}, function(result) {
|
||||||
|
var folder, list;
|
||||||
|
if (result.data.items.length) {
|
||||||
|
list = result.data.items[0];
|
||||||
|
folder = list.status == 'featured' ? 'featured' : (
|
||||||
|
list.user == app.user.username ? 'personal' : 'favorite'
|
||||||
|
);
|
||||||
|
app.$ui.folderList[folder]
|
||||||
|
.options('selected', [app.user.ui.list])
|
||||||
|
.gainFocus();
|
||||||
|
} else {
|
||||||
|
app.user.ui.list = '';
|
||||||
|
//app.user.ui.listQuery.conditions = []; // fixme: Query should read from pandora.ui.list, and not need pandora.ui.listQuery to be reset
|
||||||
|
//pandora.URL.set(pandora.Query.toString());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
356
static/js/pandora/ui/account.js
Normal file
356
static/js/pandora/ui/account.js
Normal file
|
@ -0,0 +1,356 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
|
||||||
|
pandora.ui.accountDialog = function(action) {
|
||||||
|
var that = new Ox.Dialog($.extend({
|
||||||
|
height: 256,
|
||||||
|
id: 'accountDialog',
|
||||||
|
minHeight: 256,
|
||||||
|
minWidth: 384,
|
||||||
|
width: 384
|
||||||
|
}, pandora.ui.accountDialogOptions(action)))
|
||||||
|
.bindEvent({
|
||||||
|
resize: function(event, data) {
|
||||||
|
var width = data.width - 32;
|
||||||
|
app.$ui.accountForm.items.forEach(function(item) {
|
||||||
|
item.options({width: width});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
pandora.ui.accountDialogOptions = function(action, value) {
|
||||||
|
//Ox.print('ACTION', action)
|
||||||
|
app.$ui.accountForm && app.$ui.accountForm.removeElement();
|
||||||
|
var buttons = {
|
||||||
|
login: ['register', 'reset'],
|
||||||
|
register: ['login'],
|
||||||
|
reset: ['login'],
|
||||||
|
resetAndLogin: []
|
||||||
|
},
|
||||||
|
buttonTitle = {
|
||||||
|
login: 'Login',
|
||||||
|
register: 'Register',
|
||||||
|
reset: 'Reset Password',
|
||||||
|
resetAndLogin: 'Reset Password and Login'
|
||||||
|
},
|
||||||
|
dialogText = {
|
||||||
|
login: 'To login to your account, please enter your username and password.',
|
||||||
|
register: 'To create a new account, please choose a username and password, and enter your e-mail address.',
|
||||||
|
reset: 'To reset your password, please enter either your username or your e-mail address.',
|
||||||
|
resetAndLogin: 'To login to your account, please choose a new password, and enter the code that we have just e-mailed to you.'
|
||||||
|
},
|
||||||
|
dialogTitle = {
|
||||||
|
login: 'Login',
|
||||||
|
register: 'Register',
|
||||||
|
reset: 'Reset Password',
|
||||||
|
resetAndLogin: 'Reset Password'
|
||||||
|
};
|
||||||
|
function button(type) {
|
||||||
|
if (type == 'cancel') {
|
||||||
|
return new Ox.Button({
|
||||||
|
id: 'cancel' + Ox.toTitleCase(action),
|
||||||
|
title: 'Cancel'
|
||||||
|
}).bindEvent('click', function() {
|
||||||
|
app.$ui.accountDialog.close();
|
||||||
|
});
|
||||||
|
} else if (type == 'submit') {
|
||||||
|
return new Ox.Button({
|
||||||
|
disabled: true,
|
||||||
|
id: 'submit' + Ox.toTitleCase(action),
|
||||||
|
title: buttonTitle[action]
|
||||||
|
}).bindEvent('click', function() {
|
||||||
|
app.$ui.accountForm.submit();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return new Ox.Button({
|
||||||
|
id: type,
|
||||||
|
title: buttonTitle[type] + '...'
|
||||||
|
}).bindEvent('click', function() {
|
||||||
|
//Ox.print('CLICK EVENT', type)
|
||||||
|
app.$ui.accountDialog.options(ui.accountDialogOptions(type));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
buttons: [
|
||||||
|
$.map(buttons[action], function(type) {
|
||||||
|
return button(type);
|
||||||
|
}),
|
||||||
|
[button('cancel'), button('submit')]
|
||||||
|
],
|
||||||
|
content: new Ox.Element()
|
||||||
|
.append(
|
||||||
|
new Ox.Element()
|
||||||
|
.addClass('OxText')
|
||||||
|
.html(dialogText[action] + '<br/><br/>')
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
app.$ui.accountForm = pandora.ui.accountForm(action, value)
|
||||||
|
),
|
||||||
|
keys: {
|
||||||
|
enter: 'submit' + Ox.toTitleCase(action),
|
||||||
|
escape: 'cancel' + Ox.toTitleCase(action)
|
||||||
|
},
|
||||||
|
title: dialogTitle[action]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pandora.ui.accountForm = function(action, value) {
|
||||||
|
if (app.$ui.accountForm) {
|
||||||
|
app.$ui.accountForm.items.forEach(function(item) {
|
||||||
|
if (item.options('id') == 'usernameOrEmail') {
|
||||||
|
//Ox.print('REMOVING')
|
||||||
|
//Ox.Event.unbind('usernameOrEmailSelect')
|
||||||
|
//Ox.Event.unbind('usernameOrEmailSelectMenu')
|
||||||
|
//Ox.Event.unbind('usernameOrEmailInput')
|
||||||
|
}
|
||||||
|
//Ox.print('REMOVING ITEM', item.options('id'));
|
||||||
|
item.removeElement();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var items = {
|
||||||
|
'login': ['username', 'password'],
|
||||||
|
'register': ['newUsername', 'password', 'email'],
|
||||||
|
'reset': ['usernameOrEmail'],
|
||||||
|
'resetAndLogin': ['oldUsername', 'newPassword', 'code']
|
||||||
|
},
|
||||||
|
$items = $.map(items[action], function(v) {
|
||||||
|
return item(v, value);
|
||||||
|
}),
|
||||||
|
that = new Ox.Form({
|
||||||
|
id: 'accountForm' + Ox.toTitleCase(action),
|
||||||
|
items: $items,
|
||||||
|
submit: function(data, callback) {
|
||||||
|
if (action == 'login') {
|
||||||
|
pandora.api.signin(data, function(result) {
|
||||||
|
if (!result.data.errors) {
|
||||||
|
app.$ui.accountDialog.close();
|
||||||
|
pandora.login(result.data);
|
||||||
|
} else {
|
||||||
|
callback([{id: 'password', message: 'Incorrect password'}]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (action == 'register') {
|
||||||
|
pandora.api.signup(data, function(result) {
|
||||||
|
if (!result.data.errors) {
|
||||||
|
app.$ui.accountDialog.close();
|
||||||
|
pandora.login(result.data);
|
||||||
|
pandora.ui.accountWelcomeDialog().open();
|
||||||
|
} else {
|
||||||
|
callback([{id: 'password', message: result.data.errors.toString()}]); // fixme
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (action == 'reset') {
|
||||||
|
var usernameOrEmail = data.usernameOrEmail,
|
||||||
|
key = usernameOrEmail[0].id;
|
||||||
|
data = {};
|
||||||
|
data[key] = usernameOrEmail[1];
|
||||||
|
pandora.api.requestToken(data, function(result) {
|
||||||
|
if (!result.data.errors) {
|
||||||
|
app.$ui.accountDialog.options(ui.accountDialogOptions('resetAndLogin', result.data.username));
|
||||||
|
} else {
|
||||||
|
callback([{id: 'usernameOrEmail', message: 'Unknown ' + (key == 'username' ? 'username' : 'e-mail address')}])
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (action == 'resetAndLogin') {
|
||||||
|
pandora.api.resetPassword(data, function(result) {
|
||||||
|
if (!result.data.errors) {
|
||||||
|
app.$ui.accountDialog.close();
|
||||||
|
pandora.login(result.data);
|
||||||
|
} else {
|
||||||
|
callback([{id: 'code', message: 'Incorrect code'}]);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).bindEvent({
|
||||||
|
submit: function(event, data) {
|
||||||
|
|
||||||
|
},
|
||||||
|
validate: function(event, data) {
|
||||||
|
//Ox.print('FORM VALIDATE', data)
|
||||||
|
app.$ui.accountDialog[
|
||||||
|
(data.valid ? 'enable' : 'disable') + 'Button'
|
||||||
|
]('submit' + Ox.toTitleCase(action));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
that.items = $items;
|
||||||
|
function item(type, value) {
|
||||||
|
if (type == 'code') {
|
||||||
|
return new Ox.Input({
|
||||||
|
autovalidate: autovalidateCode,
|
||||||
|
id: 'code',
|
||||||
|
label: 'Code',
|
||||||
|
labelWidth: 120,
|
||||||
|
validate: function(value, callback) {
|
||||||
|
callback({
|
||||||
|
message: 'Missing code',
|
||||||
|
valid: !!value.length
|
||||||
|
});
|
||||||
|
},
|
||||||
|
width: 352
|
||||||
|
});
|
||||||
|
} else if (type == 'email') {
|
||||||
|
return new Ox.Input({
|
||||||
|
autovalidate: autovalidateEmail,
|
||||||
|
id: 'email',
|
||||||
|
label: 'E-Mail Address',
|
||||||
|
labelWidth: 120,
|
||||||
|
type: 'email',
|
||||||
|
validate: pandora.validateUser('email'),
|
||||||
|
width: 352
|
||||||
|
});
|
||||||
|
} else if (type == 'newPassword') {
|
||||||
|
return new Ox.Input({
|
||||||
|
autovalidate: /.+/,
|
||||||
|
id: 'password',
|
||||||
|
label: 'New Password',
|
||||||
|
labelWidth: 120,
|
||||||
|
type: 'password',
|
||||||
|
validate: function(value, callback) {
|
||||||
|
callback({
|
||||||
|
message: 'Missing password',
|
||||||
|
valid: value.length > 0
|
||||||
|
});
|
||||||
|
},
|
||||||
|
width: 352
|
||||||
|
});
|
||||||
|
} else if (type == 'newUsername') {
|
||||||
|
return new Ox.Input({
|
||||||
|
autovalidate: pandora.autovalidateUsername,
|
||||||
|
id: 'username',
|
||||||
|
label: 'Username',
|
||||||
|
labelWidth: 120,
|
||||||
|
validate: pandora.validateUser('username'),
|
||||||
|
width: 352
|
||||||
|
});
|
||||||
|
} else if (type == 'oldUsername') {
|
||||||
|
return new Ox.Input({
|
||||||
|
disabled: true,
|
||||||
|
id: 'username',
|
||||||
|
label: 'Username',
|
||||||
|
labelWidth: 120,
|
||||||
|
value: value,
|
||||||
|
width: 352
|
||||||
|
});
|
||||||
|
} else if (type == 'password') {
|
||||||
|
return new Ox.Input({
|
||||||
|
autovalidate: /.+/,
|
||||||
|
id: 'password',
|
||||||
|
label: 'Password',
|
||||||
|
labelWidth: 120,
|
||||||
|
type: 'password',
|
||||||
|
validate: function(value, callback) {
|
||||||
|
callback({
|
||||||
|
message: 'Missing Password',
|
||||||
|
valid: value.length > 0
|
||||||
|
});
|
||||||
|
},
|
||||||
|
width: 352
|
||||||
|
});
|
||||||
|
} else if (type == 'username') {
|
||||||
|
return new Ox.Input({
|
||||||
|
autovalidate: pandora.autovalidateUsername,
|
||||||
|
id: 'username',
|
||||||
|
label: 'Username',
|
||||||
|
labelWidth: 120,
|
||||||
|
validate: pandora.validateUser('username', true),
|
||||||
|
width: 352
|
||||||
|
});
|
||||||
|
} else if (type == 'usernameOrEmail') {
|
||||||
|
return new Ox.FormElementGroup({
|
||||||
|
id: 'usernameOrEmail',
|
||||||
|
elements: [
|
||||||
|
app.$ui.usernameOrEmailSelect = new Ox.Select({
|
||||||
|
id: 'usernameOrEmailSelect',
|
||||||
|
items: [
|
||||||
|
{id: 'username', title: 'Username'},
|
||||||
|
{id: 'email', title: 'E-Mail Address'},
|
||||||
|
],
|
||||||
|
overlap: 'right',
|
||||||
|
width: 120
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
var selected = data.selected[0].id;
|
||||||
|
app.$ui.usernameOrEmailInput.options({
|
||||||
|
autovalidate: selected == 'username' ? pandora.autovalidateUsername : autovalidateEmail,
|
||||||
|
validate: validateUser(selected, true),
|
||||||
|
value: ''
|
||||||
|
}).focus();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
app.$ui.usernameOrEmailInput = new Ox.Input({
|
||||||
|
autovalidate: pandora.autovalidateUsername,
|
||||||
|
id: 'usernameOrEmailInput',
|
||||||
|
validate: pandora.validateUser('username', true),
|
||||||
|
width: 232
|
||||||
|
})
|
||||||
|
],
|
||||||
|
separators: [
|
||||||
|
{title: '', width: 0}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
pandora.ui.accountLogoutDialog = function() {
|
||||||
|
var that = new Ox.Dialog({
|
||||||
|
buttons: [
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'cancel',
|
||||||
|
title: 'Cancel'
|
||||||
|
}).bindEvent('click', function() {
|
||||||
|
that.close();
|
||||||
|
app.$ui.mainMenu.getItem('loginlogout').toggleTitle();
|
||||||
|
}),
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'logout',
|
||||||
|
title: 'Logout'
|
||||||
|
}).bindEvent('click', function() {
|
||||||
|
that.close();
|
||||||
|
pandora.api.signout({}, function(result) {
|
||||||
|
pandora.logout(result.data);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
],
|
||||||
|
content: new Ox.Element().html('Are you sure you want to logout?'),
|
||||||
|
height: 160,
|
||||||
|
keys: {enter: 'logout', escape: 'cancel'},
|
||||||
|
title: 'Logout',
|
||||||
|
width: 300
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
pandora.ui.accountWelcomeDialog = function() {
|
||||||
|
var that = new Ox.Dialog({
|
||||||
|
buttons: [
|
||||||
|
[
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'preferences',
|
||||||
|
title: 'Preferences...'
|
||||||
|
}).bindEvent('click', function() {
|
||||||
|
that.close();
|
||||||
|
})
|
||||||
|
],
|
||||||
|
[
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'close',
|
||||||
|
title: 'Close'
|
||||||
|
}).bindEvent('click', function() {
|
||||||
|
that.close();
|
||||||
|
})
|
||||||
|
]
|
||||||
|
],
|
||||||
|
content: new Ox.Element().html('Welcome, ' + app.user.username + '!<br/><br/>Your account has been created.'),
|
||||||
|
height: 160,
|
||||||
|
keys: {enter: 'close', escape: 'close'},
|
||||||
|
title: 'Welcome to ' + app.config.site.name,
|
||||||
|
width: 300
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
29
static/js/pandora/ui/appPanel.js
Normal file
29
static/js/pandora/ui/appPanel.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.appPanel = function() {
|
||||||
|
var that = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: app.$ui.mainMenu = pandora.ui.mainMenu(),
|
||||||
|
size: 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.mainPanel = pandora.ui.mainPanel()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'vertical'
|
||||||
|
});
|
||||||
|
that.display = function() {
|
||||||
|
// fixme: move animation into Ox.App
|
||||||
|
app.$ui.body.css({opacity: 0});
|
||||||
|
that.appendTo(app.$ui.body);
|
||||||
|
app.$ui.body.animate({opacity: 1}, 1000);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
that.reload = function() {
|
||||||
|
app.$ui.appPanel.removeElement();
|
||||||
|
app.$ui.appPanel = pandora.ui.appPanel().appendTo(app.$ui.body);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
16
static/js/pandora/ui/backButton.js
Normal file
16
static/js/pandora/ui/backButton.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.backButton = function() {
|
||||||
|
var that = Ox.Button({
|
||||||
|
title: 'Back to ' + app.config.itemName.plural,
|
||||||
|
width: 96
|
||||||
|
}).css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function(event, data) {
|
||||||
|
pandora.URL.set(pandora.Query.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
91
static/js/pandora/ui/browser.js
Normal file
91
static/js/pandora/ui/browser.js
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.browser = function() {
|
||||||
|
var that;
|
||||||
|
if (!app.user.ui.item) {
|
||||||
|
app.$ui.groups = pandora.ui.groups();
|
||||||
|
that = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: app.$ui.groups[0],
|
||||||
|
size: app.ui.groups[0].size
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.groupsInnerPanel = pandora.ui.groupsInnerPanel()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.groups[4],
|
||||||
|
size: app.ui.groups[4].size
|
||||||
|
},
|
||||||
|
],
|
||||||
|
id: 'browser',
|
||||||
|
orientation: 'horizontal'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
resize: function(event, data) {
|
||||||
|
app.user.ui.groupsSize = data;
|
||||||
|
$.each(app.$ui.groups, function(i, list) {
|
||||||
|
list.size();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resizeend: function(event, data){
|
||||||
|
pandora.UI.set({groupsSize: data});
|
||||||
|
},
|
||||||
|
toggle: function(event, data) {
|
||||||
|
pandora.UI.set({showGroups: !data.collapsed});
|
||||||
|
data.collapsed && app.$ui.list.gainFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var that = new Ox.IconList({
|
||||||
|
centered: true,
|
||||||
|
id: 'list',
|
||||||
|
item: function(data, sort, size) {
|
||||||
|
var ratio = data.poster.width / data.poster.height;
|
||||||
|
size = size || 64;
|
||||||
|
return {
|
||||||
|
height: ratio <= 1 ? size : size / ratio,
|
||||||
|
id: data['id'],
|
||||||
|
info: data[['title', 'director'].indexOf(sort[0].key) > -1 ? 'year' : sort[0].key],
|
||||||
|
title: data.title + (data.director ? ' (' + data.director + ')' : ''),
|
||||||
|
url: data.poster.url.replace(/jpg/, size + '.jpg'),
|
||||||
|
width: ratio >= 1 ? size : size * ratio
|
||||||
|
};
|
||||||
|
},
|
||||||
|
items: function(data, callback) {
|
||||||
|
//Ox.print('data, pandora.Query.toObject', data, pandora.Query.toObject())
|
||||||
|
pandora.api.find($.extend(data, {
|
||||||
|
query: pandora.Query.toObject()
|
||||||
|
}), callback);
|
||||||
|
},
|
||||||
|
keys: ['director', 'id', 'poster', 'title', 'year'],
|
||||||
|
max: 1,
|
||||||
|
min: 1,
|
||||||
|
orientation: 'horizontal',
|
||||||
|
selected: [app.user.ui.item],
|
||||||
|
size: 64,
|
||||||
|
sort: app.user.ui.lists[app.user.ui.list].sort,
|
||||||
|
unique: 'id'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
open: function(event, data) {
|
||||||
|
that.scrollToSelection();
|
||||||
|
},
|
||||||
|
select: function(event, data) {
|
||||||
|
pandora.URL.set(data.ids[0]);
|
||||||
|
},
|
||||||
|
toggle: function(event, data) {
|
||||||
|
pandora.UI.set({showMovies: !data.collapsed});
|
||||||
|
if (data.collapsed) {
|
||||||
|
if (app.user.ui.itemView == 'timeline') {
|
||||||
|
app.$ui.editor.gainFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
that.update = function() {
|
||||||
|
app.$ui.contentPanel.replaceElement(0, app.$ui.browser = pandora.ui.browser());
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
31
static/js/pandora/ui/contentPanel.js
Normal file
31
static/js/pandora/ui/contentPanel.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.contentPanel = function() {
|
||||||
|
var that = new Ox.SplitPanel({
|
||||||
|
elements: app.user.ui.item == '' ? [
|
||||||
|
{
|
||||||
|
collapsed: !app.user.ui.showGroups,
|
||||||
|
collapsible: true,
|
||||||
|
element: app.$ui.browser = pandora.ui.browser(),
|
||||||
|
resizable: true,
|
||||||
|
resize: [96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256],
|
||||||
|
size: app.user.ui.groupsSize
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.list = pandora.ui.list(app.user.ui.lists[app.user.ui.list].listView)
|
||||||
|
}
|
||||||
|
] : [
|
||||||
|
{
|
||||||
|
collapsed: !app.user.ui.showMovies,
|
||||||
|
collapsible: true,
|
||||||
|
element: app.$ui.browser = pandora.ui.browser(),
|
||||||
|
size: 112 + Ox.UI.SCROLLBAR_SIZE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.item = pandora.ui.item(app.user.ui.item, app.user.ui.itemView)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'vertical'
|
||||||
|
})
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
44
static/js/pandora/ui/editor.js
Normal file
44
static/js/pandora/ui/editor.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.annotations = function() {
|
||||||
|
var that = new Ox.Element({
|
||||||
|
id: 'annotations'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
resize: function(event, data) {
|
||||||
|
app.user.ui.annotationsSize = data;
|
||||||
|
},
|
||||||
|
resizeend: function(event, data) {
|
||||||
|
pandora.UI.set({annotationsSize: data});
|
||||||
|
},
|
||||||
|
toggle: function(event, data) {
|
||||||
|
pandora.UI.set({showAnnotations: !data.collapsed});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
$bins = [];
|
||||||
|
$.each(app.config.layers, function(i, layer) {
|
||||||
|
var $bin = new Ox.CollapsePanel({
|
||||||
|
id: layer.id,
|
||||||
|
size: 16,
|
||||||
|
title: layer.title
|
||||||
|
});
|
||||||
|
$bins.push($bin);
|
||||||
|
$bin.$content.append(
|
||||||
|
$('<div>').css({ height: '20px' }).append(
|
||||||
|
$('<div>').css({ float: 'left', width: '16px', height: '16px', margin: '1px'}).append(
|
||||||
|
$('<img>').attr({ src: Ox.UI.getImagePath('iconFind.svg') }).css({ width: '16px', height: '16px', border: 0, background: 'rgb(64, 64, 64)', WebkitBorderRadius: '2px' })
|
||||||
|
)
|
||||||
|
).append(
|
||||||
|
$('<div>').css({ float: 'left', width: '122px', height: '14px', margin: '2px' }).html('Foo')
|
||||||
|
).append(
|
||||||
|
$('<div>').css({ float: 'left', width: '40px', height: '14px', margin: '2px', textAlign: 'right' }).html('23')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
$.each($bins, function(i, bin) {
|
||||||
|
that.append(bin);
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
21
static/js/pandora/ui/filter.js
Normal file
21
static/js/pandora/ui/filter.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.filter = function() {
|
||||||
|
var that = new Ox.Filter({
|
||||||
|
findKeys: $.map(app.config.itemKeys, function(key) {
|
||||||
|
return {
|
||||||
|
autocomplete: key.autocomplete,
|
||||||
|
autocompleteSortKey: key.autocompleteSortKey,
|
||||||
|
format: key.format,
|
||||||
|
id: key.id,
|
||||||
|
title: key.title,
|
||||||
|
type: key.type == 'layer' ? Ox.getObjectById(
|
||||||
|
app.config.layers, key.id
|
||||||
|
).type : key.type
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
sortKeys: app.ui.sortKeys,
|
||||||
|
viewKeys: app.config.listViews
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
41
static/js/pandora/ui/filterDialog.js
Normal file
41
static/js/pandora/ui/filterDialog.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.filterDialog = function() {
|
||||||
|
var that = new Ox.Dialog({
|
||||||
|
buttons: [
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'debug',
|
||||||
|
title: 'Debug',
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
alert(JSON.stringify(app.$ui.filter.options('query')));
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'cancel',
|
||||||
|
title: 'Cancel'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
app.$ui.filterDialog.close();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'save',
|
||||||
|
title: 'Save'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function() {
|
||||||
|
app.$ui.filterDialog.close();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
content: app.$ui.filter = new pandora.ui.filter(),
|
||||||
|
height: 264,
|
||||||
|
keys: {enter: 'save', escape: 'cancel'},
|
||||||
|
title: 'Advanced Find',
|
||||||
|
width: 616 + Ox.UI.SCROLLBAR_SIZE
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
127
static/js/pandora/ui/findElement.js
Normal file
127
static/js/pandora/ui/findElement.js
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.findElement = function() {
|
||||||
|
var findKey = '',
|
||||||
|
findValue = '';
|
||||||
|
if (app.user.ui.findQuery.conditions.length == 1) {
|
||||||
|
findKey = app.user.ui.findQuery.conditions[0].key;
|
||||||
|
findValue = app.user.ui.findQuery.conditions[0].value;
|
||||||
|
}
|
||||||
|
var that = new Ox.FormElementGroup({
|
||||||
|
elements: $.merge(app.user.ui.list ? [
|
||||||
|
app.$ui.findListSelect = new Ox.Select({
|
||||||
|
items: [
|
||||||
|
{id: 'all', title: 'Find: All ' + app.config.itemName.plural},
|
||||||
|
{id: 'list', title: 'Find: This List'}
|
||||||
|
],
|
||||||
|
overlap: 'right',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
var key = data.selected[0].id;
|
||||||
|
app.$ui.findInput.options({
|
||||||
|
autocomplete: autocompleteFunction()
|
||||||
|
}).focus();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
] : [], [
|
||||||
|
app.$ui.findSelect = new Ox.Select({
|
||||||
|
id: 'select',
|
||||||
|
items: $.merge($.merge([{
|
||||||
|
id: 'all',
|
||||||
|
title: 'Find: All'
|
||||||
|
}], $.map(app.ui.findKeys, function(key, i) {
|
||||||
|
return {
|
||||||
|
id: key.id,
|
||||||
|
checked: key.id == findKey,
|
||||||
|
title: 'Find: ' + key.title
|
||||||
|
};
|
||||||
|
})), [{}, {
|
||||||
|
id: 'advanced',
|
||||||
|
title: 'Find: Advanced'
|
||||||
|
}]),
|
||||||
|
overlap: 'right',
|
||||||
|
width: 112
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
var key = data.selected[0].id;
|
||||||
|
if (key == 'advanced') {
|
||||||
|
app.$ui.filterDialog = pandora.ui.filterDialog().open();
|
||||||
|
} else {
|
||||||
|
if (!app.user.ui.findQuery.conditions.length) { // fixme: can this case happen at all?
|
||||||
|
app.user.ui.findQuery.conditions = [{key: key, value: '', operator: ''}];
|
||||||
|
} else {
|
||||||
|
app.user.ui.findQuery.conditions[0].key = key;
|
||||||
|
}
|
||||||
|
app.$ui.mainMenu.checkItem('findMenu_find_' + key);
|
||||||
|
app.$ui.findInput.options({
|
||||||
|
autocomplete: autocompleteFunction()
|
||||||
|
}).focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
app.$ui.findInput = new Ox.Input({
|
||||||
|
autocomplete: autocompleteFunction(),
|
||||||
|
autocompleteSelect: true,
|
||||||
|
autocompleteSelectHighlight: true,
|
||||||
|
autocompleteSelectSubmit: true,
|
||||||
|
clear: true,
|
||||||
|
id: 'input',
|
||||||
|
value: findValue,
|
||||||
|
width: 192
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
submit: function(event, data) {
|
||||||
|
var key = app.user.ui.findQuery.conditions.length ?
|
||||||
|
app.user.ui.findQuery.conditions[0].key : '';
|
||||||
|
if (app.user.ui.list && that.value()[0].id == 'all') {
|
||||||
|
$.each(app.$ui.folderList, function(k, $list) {
|
||||||
|
$list.options({selected: []});
|
||||||
|
});
|
||||||
|
pandora.UI.set({list: ''});
|
||||||
|
app.user.ui.listQuery = {conditions: [], operator: ''};
|
||||||
|
}
|
||||||
|
app.user.ui.findQuery.conditions = [{
|
||||||
|
key: key == 'all' ? '' : key,
|
||||||
|
value: data.value,
|
||||||
|
operator: ''
|
||||||
|
}];
|
||||||
|
pandora.URL.set(pandora.Query.toString());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]),
|
||||||
|
id: 'findElement'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'right',
|
||||||
|
margin: '4px'
|
||||||
|
});
|
||||||
|
function autocompleteFunction() {
|
||||||
|
return app.user.ui.findQuery.conditions.length ? function(value, callback) {
|
||||||
|
var elementValue = that.value(),
|
||||||
|
key = elementValue[app.user.ui.list ? 1 : 0].id,
|
||||||
|
findKey = Ox.getObjectById(app.ui.findKeys, key);
|
||||||
|
Ox.print('!!!!', key, findKey, 'autocomplete' in findKey && findKey.autocomplete)
|
||||||
|
value === '' && Ox.print('Warning: autocomplete function should never be called with empty value');
|
||||||
|
if ('autocomplete' in findKey && findKey.autocomplete) {
|
||||||
|
pandora.api.autocomplete({
|
||||||
|
key: key,
|
||||||
|
query: elementValue[0].id == 'list' ? app.user.ui.listQuery : {conditions: [], operator: ''},
|
||||||
|
range: [0, 20],
|
||||||
|
sort: [{
|
||||||
|
key: 'votes',
|
||||||
|
operator: '-'
|
||||||
|
}],
|
||||||
|
value: value
|
||||||
|
}, function(result) {
|
||||||
|
callback(result.data.items);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback([]);
|
||||||
|
}
|
||||||
|
} : null;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
26
static/js/pandora/ui/flipbook.js
Normal file
26
static/js/pandora/ui/flipbook.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.flipbook = function(item) {
|
||||||
|
var that = new Ox.Flipbook({
|
||||||
|
}).bindEvent('click', function(event, data) {
|
||||||
|
pandora.UI.set('videoPosition|' + item, data.position);
|
||||||
|
pandora.URL.set(item + '/timeline');
|
||||||
|
});
|
||||||
|
pandora.api.getItem(item, function(result) {
|
||||||
|
var duration = result.data.item.duration,
|
||||||
|
posterFrame = result.data.item.posterFrame || parseInt(duration/2),
|
||||||
|
steps = 24,
|
||||||
|
framePrefix = '/' + item + '/frame/' + that.width() + '/',
|
||||||
|
frames = {};
|
||||||
|
Ox.range(0, duration, duration/steps).forEach(function(position) {
|
||||||
|
position = parseInt(position);
|
||||||
|
frames[position] = framePrefix + position + '.jpg';
|
||||||
|
});
|
||||||
|
that.options({
|
||||||
|
frames: frames,
|
||||||
|
icon: framePrefix + posterFrame + '.jpg',
|
||||||
|
duration: duration
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
17
static/js/pandora/ui/folderBrowser.js
Normal file
17
static/js/pandora/ui/folderBrowser.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.folderBrowser = function(id) {
|
||||||
|
var that = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: pandora.ui.folderBrowserBar(),
|
||||||
|
size: 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.folderList[id] = pandora.ui.folderBrowserList(id)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'vertical'
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
17
static/js/pandora/ui/folderBrowserBar.js
Normal file
17
static/js/pandora/ui/folderBrowserBar.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.folderBrowserBar = function(id) {
|
||||||
|
var that = new Ox.Bar({
|
||||||
|
size: 24
|
||||||
|
});
|
||||||
|
app.$ui.findListInput = new Ox.Input({
|
||||||
|
placeholder: 'Find User',
|
||||||
|
width: 184 - Ox.UI.SCROLLBAR_SIZE
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
margin: '4px',
|
||||||
|
align: 'right'
|
||||||
|
})
|
||||||
|
.appendTo(that);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
664
static/js/pandora/ui/folderBrowserList.js
Normal file
664
static/js/pandora/ui/folderBrowserList.js
Normal file
|
@ -0,0 +1,664 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.folderBrowserList = function(id) {
|
||||||
|
var columnWidth = (app.user.ui.sidebarSize - Ox.UI.SCROLLBAR_SIZE - 88) / 2,
|
||||||
|
i = Ox.getPositionById(app.ui.sectionFolders[app.user.ui.section], id),
|
||||||
|
that = new Ox.TextList({
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
format: function() {
|
||||||
|
return $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/icon16.png'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
id: 'id',
|
||||||
|
operator: '+',
|
||||||
|
title: $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/icon16.png'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: '10px',
|
||||||
|
height: '10px',
|
||||||
|
padding: '3px 2px 1px 2px',
|
||||||
|
}),
|
||||||
|
unique: true,
|
||||||
|
visible: true,
|
||||||
|
width: 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
operator: '+',
|
||||||
|
title: 'User',
|
||||||
|
visible: true,
|
||||||
|
width: Math.floor(columnWidth)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'name',
|
||||||
|
operator: '+',
|
||||||
|
title: 'List',
|
||||||
|
visible: true,
|
||||||
|
width: Math.ceil(columnWidth)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
id: 'items',
|
||||||
|
operator: '-',
|
||||||
|
title: 'Items',
|
||||||
|
visible: true,
|
||||||
|
width: 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
clickable: function(data) {
|
||||||
|
return data.type == 'smart';
|
||||||
|
},
|
||||||
|
format: function(value) {
|
||||||
|
return $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.getImagePath('symbolFind.svg')
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: '10px',
|
||||||
|
height: '10px',
|
||||||
|
padding: '3px 2px 1px 2px', // fixme: strange
|
||||||
|
opacity: value == 'static' ? 0.1 : 1
|
||||||
|
});
|
||||||
|
},
|
||||||
|
id: 'type',
|
||||||
|
operator: '+',
|
||||||
|
title: $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.getImagePath('symbolFind.svg')
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: '10px',
|
||||||
|
height: '10px',
|
||||||
|
padding: '3px 2px 1px 2px',
|
||||||
|
}),
|
||||||
|
visible: true,
|
||||||
|
width: 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
clickable: true,
|
||||||
|
format: function(value) {
|
||||||
|
return $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.getImagePath(
|
||||||
|
'symbol' + (id == 'favorite' ? 'Check' : 'Star') + '.svg'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: '10px',
|
||||||
|
height: '10px',
|
||||||
|
padding: '3px 2px 1px 2px',
|
||||||
|
opacity: id == 'favorite' ? (value ? 1 : 0.1) :
|
||||||
|
(value == 'featured' ? 1 : 0.1)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
id: id == 'favorite' ? 'subscribed' : 'status',
|
||||||
|
operator: '+',
|
||||||
|
title: $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.getImagePath(
|
||||||
|
'symbol' + (id == 'favorite' ? 'Check' : 'Star') + '.svg'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: '10px',
|
||||||
|
height: '10px',
|
||||||
|
padding: '3px 2px 1px 2px'
|
||||||
|
}),
|
||||||
|
visible: true,
|
||||||
|
width: 16
|
||||||
|
},
|
||||||
|
],
|
||||||
|
columnsVisible: true,
|
||||||
|
items: function(data, callback) {
|
||||||
|
var query = id == 'favorite' ? {conditions: [
|
||||||
|
{key: 'user', value: app.user.username, operator: '!'},
|
||||||
|
{key: 'status', value: 'public', operator: '='}
|
||||||
|
], operator: '&'} : {conditions: [
|
||||||
|
{key: 'status', value: 'public', operator: '='},
|
||||||
|
{key: 'status', value: 'featured', operator: '='}
|
||||||
|
], operator: '|'};
|
||||||
|
return pandora.api.findLists($.extend(data, {
|
||||||
|
query: query
|
||||||
|
}), callback);
|
||||||
|
},
|
||||||
|
pageLength: 1000,
|
||||||
|
// fixme: select if previously selected
|
||||||
|
// selected: app.user.ui.list ? [app.user.ui.list] : [],
|
||||||
|
sort: [
|
||||||
|
{key: 'name', operator: '+'}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function(event, data) {
|
||||||
|
if (data.key == 'type') {
|
||||||
|
alert('...');
|
||||||
|
} else if (data.key == 'subscribed') {
|
||||||
|
var subscribed = that.value(data.id, 'subscribed');
|
||||||
|
pandora.api[subscribed ? 'unsubscribeFromList' : 'subscribeToList']({
|
||||||
|
id: data.id,
|
||||||
|
}, function(result) {
|
||||||
|
that.value(data.id, 'subscribed', !subscribed);
|
||||||
|
});
|
||||||
|
} else if (data.key == 'status') {
|
||||||
|
pandora.api.editList({
|
||||||
|
id: data.id,
|
||||||
|
status: that.value(data.id, 'status') == 'featured' ? 'public' : 'featured'
|
||||||
|
}, function(result) {
|
||||||
|
Ox.print('result', result)
|
||||||
|
if (result.data.user == app.user.username || result.data.subscribed) {
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
app.$ui.folderList[
|
||||||
|
result.data.user == app.user.username ? 'personal' : 'favorite'
|
||||||
|
].reloadList();
|
||||||
|
}
|
||||||
|
that.value(data.id, 'status', result.data.status);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
init: function(event, data) {
|
||||||
|
app.ui.sectionFolders[app.user.ui.section][i].items = data.items;
|
||||||
|
app.$ui.folder[i].$content.css({
|
||||||
|
height: 40 + data.items * 16 + 'px'
|
||||||
|
});
|
||||||
|
app.$ui.folderList[id].css({
|
||||||
|
height: 16 + data.items * 16 + 'px'
|
||||||
|
});
|
||||||
|
pandora.resizeFolders();
|
||||||
|
},
|
||||||
|
paste: function(event, data) {
|
||||||
|
app.$ui.list.triggerEvent('paste', data);
|
||||||
|
},
|
||||||
|
select: function(event, data) {
|
||||||
|
// fixme: duplicated
|
||||||
|
if (data.ids.length) {
|
||||||
|
$.each(app.$ui.folderList, function(id_, $list) {
|
||||||
|
id != id_ && $list.options('selected', []);
|
||||||
|
});
|
||||||
|
pandora.UI.set({list: data.ids[0]});
|
||||||
|
pandora.URL.set('?find=list:' + data.ids[0]);
|
||||||
|
} else {
|
||||||
|
pandora.UI.set({list: ''});
|
||||||
|
pandora.URL.set('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
pandora.ui.folderList = function(id) {
|
||||||
|
var i = Ox.getPositionById(app.ui.sectionFolders[app.user.ui.section], id),
|
||||||
|
that;
|
||||||
|
if (app.user.ui.section == 'site') {
|
||||||
|
that = new Ox.TextList({
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
format: function() {
|
||||||
|
return $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/icon16.png'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
id: 'id',
|
||||||
|
operator: '+',
|
||||||
|
unique: true,
|
||||||
|
visible: true,
|
||||||
|
width: 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'title',
|
||||||
|
operator: '+',
|
||||||
|
visible: true,
|
||||||
|
width: app.user.ui.sidebarSize - 16
|
||||||
|
}
|
||||||
|
],
|
||||||
|
items: function(data, callback) {
|
||||||
|
var result = {data: {}};
|
||||||
|
if (!data.range) {
|
||||||
|
result.data.items = Ox.getObjectById(app.ui.sectionFolders.site, id).items.length;
|
||||||
|
} else {
|
||||||
|
result.data.items = Ox.getObjectById(app.ui.sectionFolders.site, id).items;
|
||||||
|
}
|
||||||
|
callback(result);
|
||||||
|
},
|
||||||
|
max: 1,
|
||||||
|
min: 1,
|
||||||
|
sort: [{key: '', operator: ''}]
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
select: function(event, data) {
|
||||||
|
// fixme: duplicated
|
||||||
|
$.each(app.$ui.folderList, function(id_, $list) {
|
||||||
|
id != id_ && $list.options('selected', []);
|
||||||
|
})
|
||||||
|
pandora.URL.set((id == 'admin' ? 'admin/' : '' ) + data.ids[0]);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (app.user.ui.section == 'items') {
|
||||||
|
that = new Ox.TextList({
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
format: function() {
|
||||||
|
return $('<img>').attr({
|
||||||
|
src: Ox.UI.PATH + 'png/icon16.png'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
id: 'user',
|
||||||
|
operator: '+',
|
||||||
|
visible: true,
|
||||||
|
width: 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: function(value) {
|
||||||
|
return value.split('/').join(': ');
|
||||||
|
},
|
||||||
|
id: 'id',
|
||||||
|
operator: '+',
|
||||||
|
unique: true,
|
||||||
|
visible: id == 'favorite',
|
||||||
|
width: app.user.ui.sidebarWidth - 88
|
||||||
|
},
|
||||||
|
{
|
||||||
|
editable: function(data) {
|
||||||
|
return data.user == app.user.username;
|
||||||
|
},
|
||||||
|
id: 'name',
|
||||||
|
input: {
|
||||||
|
autovalidate: pandora.ui.autovalidateListname
|
||||||
|
},
|
||||||
|
operator: '+',
|
||||||
|
visible: id != 'favorite',
|
||||||
|
width: app.user.ui.sidebarWidth - 88
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
id: 'items',
|
||||||
|
operator: '-',
|
||||||
|
visible: true,
|
||||||
|
width: 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
clickable: function(data) {
|
||||||
|
return data.type == 'smart';
|
||||||
|
},
|
||||||
|
format: function(value) {
|
||||||
|
return $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.getImagePath('symbolFind.svg')
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: '10px',
|
||||||
|
height: '10px',
|
||||||
|
padding: '3px 2px 1px 2px',
|
||||||
|
opacity: value == 'static' ? 0.1 : 1
|
||||||
|
});
|
||||||
|
},
|
||||||
|
id: 'type',
|
||||||
|
operator: '+',
|
||||||
|
visible: true,
|
||||||
|
width: 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
clickable: id == 'personal',
|
||||||
|
format: function(value) {
|
||||||
|
//var symbols = {private: 'Publish', public: 'Publish', featured: 'Star'};
|
||||||
|
return $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.getImagePath(
|
||||||
|
'symbol' + (value == 'featured' ? 'Star' : 'Publish') + '.svg'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: '10px',
|
||||||
|
height: '10px',
|
||||||
|
padding: '3px 2px 1px 2px',
|
||||||
|
opacity: value == 'private' ? 0.1 : 1
|
||||||
|
})
|
||||||
|
},
|
||||||
|
id: 'status',
|
||||||
|
operator: '+',
|
||||||
|
visible: true,
|
||||||
|
width: 16
|
||||||
|
}
|
||||||
|
],
|
||||||
|
items: function(data, callback) {
|
||||||
|
var query;
|
||||||
|
if (id == 'personal') {
|
||||||
|
query = {conditions: [
|
||||||
|
{key: 'user', value: app.user.username, operator: '='},
|
||||||
|
{key: 'status', value: 'featured', operator: '!'}
|
||||||
|
], operator: '&'};
|
||||||
|
} else if (id == 'favorite') {
|
||||||
|
query = {conditions: [
|
||||||
|
{key: 'subscribed', value: true, operator: '='},
|
||||||
|
{key: 'status', value: 'featured', operator: '!'},
|
||||||
|
], operator: '&'};
|
||||||
|
} else if (id == 'featured') {
|
||||||
|
query = {conditions: [{key: 'status', value: 'featured', operator: '='}], operator: '&'};
|
||||||
|
}
|
||||||
|
return pandora.api.findLists($.extend(data, {
|
||||||
|
query: query
|
||||||
|
}), callback);
|
||||||
|
},
|
||||||
|
max: 1,
|
||||||
|
min: 0,
|
||||||
|
pageLength: 1000,
|
||||||
|
sort: [
|
||||||
|
{key: 'position', operator: '+'}
|
||||||
|
],
|
||||||
|
sortable: id == 'personal' || id == 'favorite' || app.user.level == 'admin'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: app.user.ui.sidebarWidth + 'px',
|
||||||
|
})
|
||||||
|
.bind({
|
||||||
|
dragenter: function(e) {
|
||||||
|
//Ox.print('DRAGENTER', e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function(event, data) {
|
||||||
|
var $list = app.$ui.folderList[id];
|
||||||
|
if (data.key == 'type') {
|
||||||
|
app.$ui.filterDialog = pandora.ui.filterDialog().open();
|
||||||
|
} else if (data.key == 'status') {
|
||||||
|
pandora.api.editList({
|
||||||
|
id: data.id,
|
||||||
|
status: $list.value(data.id, data.key) == 'private' ? 'public' : 'private'
|
||||||
|
}, function(result) {
|
||||||
|
$list.value(result.data.id, 'status', result.data.status);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'delete': function(event, data) {
|
||||||
|
var $list = app.$ui.folderList[id];
|
||||||
|
app.user.ui.listQuery.conditions = [];
|
||||||
|
pandora.URL.set(pandora.Query.toString());
|
||||||
|
$list.options({selected: []});
|
||||||
|
if (id == 'personal') {
|
||||||
|
pandora.api.removeList({
|
||||||
|
id: data.ids[0]
|
||||||
|
}, function(result) {
|
||||||
|
// fixme: is this the best way to delete a ui preference?
|
||||||
|
delete app.user.ui.lists[data.ids[0]];
|
||||||
|
pandora.UI.set({lists: app.user.ui.lists});
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
$list.reloadList();
|
||||||
|
});
|
||||||
|
} else if (id == 'favorite') {
|
||||||
|
pandora.api.unsubscribeFromList({
|
||||||
|
id: data.ids[0]
|
||||||
|
}, function(result) {
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
$list.reloadList();
|
||||||
|
});
|
||||||
|
} else if (id == 'featured' && app.user.level == 'admin') {
|
||||||
|
pandora.api.editList({
|
||||||
|
id: data.ids[0],
|
||||||
|
status: 'public'
|
||||||
|
}, function(result) {
|
||||||
|
// fixme: duplicated
|
||||||
|
if (result.data.user == app.user.username || result.data.subscribed) {
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
app.$ui.folderList[
|
||||||
|
result.data.user == app.user.username ? 'personal' : 'favorite'
|
||||||
|
].reloadList();
|
||||||
|
}
|
||||||
|
$list.reloadList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
init: function(event, data) {
|
||||||
|
app.ui.sectionFolders[app.user.ui.section][i].items = data.items;
|
||||||
|
app.$ui.folder[i].$content.css({
|
||||||
|
height: data.items * 16 + 'px'
|
||||||
|
});
|
||||||
|
app.$ui.folderList[id].css({
|
||||||
|
height: data.items * 16 + 'px'
|
||||||
|
});
|
||||||
|
pandora.resizeFolders();
|
||||||
|
},
|
||||||
|
move: function(event, data) {
|
||||||
|
/*
|
||||||
|
data.ids.forEach(function(id, pos) {
|
||||||
|
app.user.ui.lists[id].position = pos;
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
pandora.api.sortLists({
|
||||||
|
section: id,
|
||||||
|
ids: data.ids
|
||||||
|
});
|
||||||
|
},
|
||||||
|
paste: function(event, data) {
|
||||||
|
app.$ui.list.triggerEvent('paste', data);
|
||||||
|
},
|
||||||
|
select: function(event, data) {
|
||||||
|
if (data.ids.length) {
|
||||||
|
$.each(app.$ui.folderList, function(id_, $list) {
|
||||||
|
id != id_ && $list.options('selected', []);
|
||||||
|
})
|
||||||
|
pandora.URL.set('?find=list:' + data.ids[0]);
|
||||||
|
} else {
|
||||||
|
pandora.URL.set('?find=');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submit: function(event, data) {
|
||||||
|
data_ = {id: data.id};
|
||||||
|
data_[data.key] = data.value;
|
||||||
|
pandora.api.editList(data_, function(result) {
|
||||||
|
if (result.data.id != data.id) {
|
||||||
|
app.$ui.folderList[id].value(data.id, 'name', result.data.name);
|
||||||
|
app.$ui.folderList[id].value(data.id, 'id', result.data.id);
|
||||||
|
pandora.URL.set('?find=list:' + result.data.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
pandora.ui.folders = function() {
|
||||||
|
var that = new Ox.Element()
|
||||||
|
.css({overflowX: 'hidden', overflowY: 'auto'})
|
||||||
|
.bindEvent({
|
||||||
|
resize: function(event, data) {
|
||||||
|
pandora.resizeFolders();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var counter = 0;
|
||||||
|
//var $sections = [];
|
||||||
|
app.$ui.folder = [];
|
||||||
|
app.$ui.folderBrowser = {};
|
||||||
|
app.$ui.folderList = {};
|
||||||
|
if (app.user.ui.section == 'site') {
|
||||||
|
$.each(app.ui.sectionFolders.site, function(i, folder) {
|
||||||
|
var height = (Ox.getObjectById(app.ui.sectionFolders.site, folder.id).items.length * 16);
|
||||||
|
app.$ui.folder[i] = new Ox.CollapsePanel({
|
||||||
|
id: folder.id,
|
||||||
|
collapsed: !app.user.ui.showFolder.site[folder.id],
|
||||||
|
size: 16,
|
||||||
|
title: folder.title
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
toggle: function(event, data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//alert(JSON.stringify(Ox.getObjectById(app.ui.sectionFolders.site, folder.id)))
|
||||||
|
app.$ui.folder[i].$content.css({
|
||||||
|
height: height + 'px'
|
||||||
|
})
|
||||||
|
//.appendTo(that);
|
||||||
|
app.$ui.folderList[folder.id] = pandora.ui.folderList(folder.id)
|
||||||
|
.css({
|
||||||
|
height: height + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(app.$ui.folder[i].$content);
|
||||||
|
app.$ui.folder.forEach(function($folder) {
|
||||||
|
that.append($folder);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//pandora.resizeFolders();
|
||||||
|
} else if (app.user.ui.section == 'items') {
|
||||||
|
$.each(app.ui.sectionFolders.items, function(i, folder) {
|
||||||
|
var extras = [];
|
||||||
|
if (folder.id == 'personal' && app.user.level != 'guest') {
|
||||||
|
extras = [new Ox.Select({
|
||||||
|
items: [
|
||||||
|
{ id: 'new', title: 'New List...' },
|
||||||
|
{ id: 'newfromselection', title: 'New List from Current Selection...', disabled: true },
|
||||||
|
{ id: 'newsmart', title: 'New Smart List...' },
|
||||||
|
{ id: 'newfromresults', title: 'New Smart List from Current Results...', disabled: true },
|
||||||
|
{},
|
||||||
|
{ id: 'addselection', title: 'Add Selection to List...' }
|
||||||
|
],
|
||||||
|
max: 0,
|
||||||
|
min: 0,
|
||||||
|
selectable: false,
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function(event, data) {
|
||||||
|
var $list = app.$ui.folderList[folder.id],
|
||||||
|
id;
|
||||||
|
if (data.id == 'new' || data.id == 'newsmart') {
|
||||||
|
pandora.api.addList({
|
||||||
|
name: 'Untitled',
|
||||||
|
status: 'private',
|
||||||
|
type: data.id == 'new' ? 'static' : 'smart'
|
||||||
|
}, function(result) {
|
||||||
|
id = result.data.id;
|
||||||
|
pandora.UI.set(['lists', id].join('|'), app.config.user.ui.lists['']); // fixme: necessary?
|
||||||
|
pandora.URL.set('?find=list:' + id)
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
$list.reloadList().bindEventOnce({
|
||||||
|
load: function(event, data) {
|
||||||
|
$list.gainFocus()
|
||||||
|
.options({selected: [id]})
|
||||||
|
.editCell(id, 'name');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})];
|
||||||
|
} else if (folder.id == 'favorite' && app.user.level != 'guest') {
|
||||||
|
extras = [new Ox.Button({
|
||||||
|
selectable: true,
|
||||||
|
style: 'symbol',
|
||||||
|
title: 'Edit',
|
||||||
|
tooltip: 'Manage Favorite Lists',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
app.ui.sectionFolders.items[i].showBrowser = !app.ui.sectionFolders.items[i].showBrowser;
|
||||||
|
if (app.ui.sectionFolders.items[i].showBrowser) {
|
||||||
|
app.$ui.folderList.favorite.replaceWith(
|
||||||
|
app.$ui.folderBrowser.favorite = pandora.ui.folderBrowser('favorite')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
app.$ui.folderBrowser.favorite.replaceWith(
|
||||||
|
app.$ui.folderList.favorite = pandora.ui.folderList('favorite')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pandora.resizeFolders();
|
||||||
|
}
|
||||||
|
})];
|
||||||
|
} else if (folder.id == 'featured' && app.user.level == 'admin') {
|
||||||
|
extras = [new Ox.Button({
|
||||||
|
selectable: true,
|
||||||
|
style: 'symbol',
|
||||||
|
title: 'Edit',
|
||||||
|
tooltip: 'Manage Featured Lists',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
app.ui.sectionFolders.items[i].showBrowser = !app.ui.sectionFolders.items[i].showBrowser;
|
||||||
|
if (app.ui.sectionFolders.items[i].showBrowser) {
|
||||||
|
app.$ui.folderList.featured.replaceWith(
|
||||||
|
app.$ui.folderBrowser.featured = pandora.ui.folderBrowser('featured'));
|
||||||
|
} else {
|
||||||
|
app.$ui.folderBrowser.featured.replaceWith(
|
||||||
|
app.$ui.folderList.featured = pandora.ui.folderList('featured')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pandora.resizeFolders();
|
||||||
|
}
|
||||||
|
})];
|
||||||
|
}
|
||||||
|
app.$ui.folder[i] = new Ox.CollapsePanel({
|
||||||
|
id: folder.id,
|
||||||
|
collapsed: !app.user.ui.showFolder.items[folder.id],
|
||||||
|
extras: extras,
|
||||||
|
size: 16,
|
||||||
|
title: folder.title
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
// fixme: duplicated
|
||||||
|
click: function(event, data) {
|
||||||
|
var $list = app.$ui.folderList[i],
|
||||||
|
hasFocus, id;
|
||||||
|
if (data.id == 'new' || data.id == 'newsmart') {
|
||||||
|
pandora.api.addList({
|
||||||
|
name: 'Untitled',
|
||||||
|
status: 'private',
|
||||||
|
type: data.id == 'new' ? 'static' : 'smart'
|
||||||
|
}, function(result) {
|
||||||
|
id = result.data.id;
|
||||||
|
pandora.URL.set('?find=list:' + id)
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
$list.reloadList().bindEventOnce({
|
||||||
|
load: function(event, data) {
|
||||||
|
$list.gainFocus()
|
||||||
|
.options({selected: [id]})
|
||||||
|
.editCell(id, 'name');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (data.id == 'browse') {
|
||||||
|
alert('??')
|
||||||
|
/*
|
||||||
|
app.$ui.sectionList[1].replaceWith(app.$ui.publicLists = pandora.ui.publicLists());
|
||||||
|
app.ui.showAllPublicLists = true;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggle: function(event, data) {
|
||||||
|
data.collapsed && app.$ui.folderList[folder.id].loseFocus();
|
||||||
|
pandora.UI.set('showFolder|items|' + folder.id, !data.collapsed);
|
||||||
|
pandora.resizeFolders();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//$sections.push(app.$ui.section[i]);
|
||||||
|
app.$ui.folderList[folder.id] = pandora.ui.folderList(folder.id)
|
||||||
|
.bindEventOnce({
|
||||||
|
init: function(event, data) {
|
||||||
|
Ox.print('init', i, counter)
|
||||||
|
if (++counter == 3) {
|
||||||
|
app.$ui.folder.forEach(function($folder) {
|
||||||
|
that.append($folder);
|
||||||
|
});
|
||||||
|
pandora.resizeFolders();
|
||||||
|
pandora.selectList(); //fixme: doesn't work
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(app.$ui.folder[i].$content);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
that.toggle = function() {
|
||||||
|
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
199
static/js/pandora/ui/folders.js
Normal file
199
static/js/pandora/ui/folders.js
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.folders = function() {
|
||||||
|
var that = new Ox.Element()
|
||||||
|
.css({overflowX: 'hidden', overflowY: 'auto'})
|
||||||
|
.bindEvent({
|
||||||
|
resize: function(event, data) {
|
||||||
|
pandora.resizeFolders();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var counter = 0;
|
||||||
|
//var $sections = [];
|
||||||
|
app.$ui.folder = [];
|
||||||
|
app.$ui.folderBrowser = {};
|
||||||
|
app.$ui.folderList = {};
|
||||||
|
if (app.user.ui.section == 'site') {
|
||||||
|
$.each(app.ui.sectionFolders.site, function(i, folder) {
|
||||||
|
var height = (Ox.getObjectById(app.ui.sectionFolders.site, folder.id).items.length * 16);
|
||||||
|
app.$ui.folder[i] = new Ox.CollapsePanel({
|
||||||
|
id: folder.id,
|
||||||
|
collapsed: !app.user.ui.showFolder.site[folder.id],
|
||||||
|
size: 16,
|
||||||
|
title: folder.title
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
toggle: function(event, data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//alert(JSON.stringify(Ox.getObjectById(app.ui.sectionFolders.site, folder.id)))
|
||||||
|
app.$ui.folder[i].$content.css({
|
||||||
|
height: height + 'px'
|
||||||
|
})
|
||||||
|
//.appendTo(that);
|
||||||
|
app.$ui.folderList[folder.id] = pandora.ui.folderList(folder.id)
|
||||||
|
.css({
|
||||||
|
height: height + 'px'
|
||||||
|
})
|
||||||
|
.appendTo(app.$ui.folder[i].$content);
|
||||||
|
app.$ui.folder.forEach(function($folder) {
|
||||||
|
that.append($folder);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//pandora.resizeFolders();
|
||||||
|
} else if (app.user.ui.section == 'items') {
|
||||||
|
$.each(app.ui.sectionFolders.items, function(i, folder) {
|
||||||
|
var extras = [];
|
||||||
|
if (folder.id == 'personal' && app.user.level != 'guest') {
|
||||||
|
extras = [new Ox.Select({
|
||||||
|
items: [
|
||||||
|
{ id: 'new', title: 'New List...' },
|
||||||
|
{ id: 'newfromselection', title: 'New List from Current Selection...', disabled: true },
|
||||||
|
{ id: 'newsmart', title: 'New Smart List...' },
|
||||||
|
{ id: 'newfromresults', title: 'New Smart List from Current Results...', disabled: true },
|
||||||
|
{},
|
||||||
|
{ id: 'addselection', title: 'Add Selection to List...' }
|
||||||
|
],
|
||||||
|
max: 0,
|
||||||
|
min: 0,
|
||||||
|
selectable: false,
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function(event, data) {
|
||||||
|
var $list = app.$ui.folderList[folder.id],
|
||||||
|
id;
|
||||||
|
if (data.id == 'new' || data.id == 'newsmart') {
|
||||||
|
pandora.api.addList({
|
||||||
|
name: 'Untitled',
|
||||||
|
status: 'private',
|
||||||
|
type: data.id == 'new' ? 'static' : 'smart'
|
||||||
|
}, function(result) {
|
||||||
|
id = result.data.id;
|
||||||
|
pandora.UI.set(['lists', id].join('|'), app.config.user.ui.lists['']); // fixme: necessary?
|
||||||
|
pandora.URL.set('?find=list:' + id)
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
$list.reloadList().bindEventOnce({
|
||||||
|
load: function(event, data) {
|
||||||
|
$list.gainFocus()
|
||||||
|
.options({selected: [id]})
|
||||||
|
.editCell(id, 'name');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})];
|
||||||
|
} else if (folder.id == 'favorite' && app.user.level != 'guest') {
|
||||||
|
extras = [new Ox.Button({
|
||||||
|
selectable: true,
|
||||||
|
style: 'symbol',
|
||||||
|
title: 'Edit',
|
||||||
|
tooltip: 'Manage Favorite Lists',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
app.ui.sectionFolders.items[i].showBrowser = !app.ui.sectionFolders.items[i].showBrowser;
|
||||||
|
if (app.ui.sectionFolders.items[i].showBrowser) {
|
||||||
|
app.$ui.folderList.favorite.replaceWith(
|
||||||
|
app.$ui.folderBrowser.favorite = pandora.ui.folderBrowser('favorite')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
app.$ui.folderBrowser.favorite.replaceWith(
|
||||||
|
app.$ui.folderList.favorite = pandora.ui.folderList('favorite')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pandora.resizeFolders();
|
||||||
|
}
|
||||||
|
})];
|
||||||
|
} else if (folder.id == 'featured' && app.user.level == 'admin') {
|
||||||
|
extras = [new Ox.Button({
|
||||||
|
selectable: true,
|
||||||
|
style: 'symbol',
|
||||||
|
title: 'Edit',
|
||||||
|
tooltip: 'Manage Featured Lists',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
app.ui.sectionFolders.items[i].showBrowser = !app.ui.sectionFolders.items[i].showBrowser;
|
||||||
|
if (app.ui.sectionFolders.items[i].showBrowser) {
|
||||||
|
app.$ui.folderList.featured.replaceWith(
|
||||||
|
app.$ui.folderBrowser.featured = pandora.ui.folderBrowser('featured'));
|
||||||
|
} else {
|
||||||
|
app.$ui.folderBrowser.featured.replaceWith(
|
||||||
|
app.$ui.folderList.featured = pandora.ui.folderList('featured')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pandora.resizeFolders();
|
||||||
|
}
|
||||||
|
})];
|
||||||
|
}
|
||||||
|
app.$ui.folder[i] = new Ox.CollapsePanel({
|
||||||
|
id: folder.id,
|
||||||
|
collapsed: !app.user.ui.showFolder.items[folder.id],
|
||||||
|
extras: extras,
|
||||||
|
size: 16,
|
||||||
|
title: folder.title
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
// fixme: duplicated
|
||||||
|
click: function(event, data) {
|
||||||
|
var $list = app.$ui.folderList[i],
|
||||||
|
hasFocus, id;
|
||||||
|
if (data.id == 'new' || data.id == 'newsmart') {
|
||||||
|
pandora.api.addList({
|
||||||
|
name: 'Untitled',
|
||||||
|
status: 'private',
|
||||||
|
type: data.id == 'new' ? 'static' : 'smart'
|
||||||
|
}, function(result) {
|
||||||
|
id = result.data.id;
|
||||||
|
pandora.URL.set('?find=list:' + id)
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
$list.reloadList().bindEventOnce({
|
||||||
|
load: function(event, data) {
|
||||||
|
$list.gainFocus()
|
||||||
|
.options({selected: [id]})
|
||||||
|
.editCell(id, 'name');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (data.id == 'browse') {
|
||||||
|
alert('??')
|
||||||
|
/*
|
||||||
|
app.$ui.sectionList[1].replaceWith(app.$ui.publicLists = pandora.ui.publicLists());
|
||||||
|
app.ui.showAllPublicLists = true;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggle: function(event, data) {
|
||||||
|
data.collapsed && app.$ui.folderList[folder.id].loseFocus();
|
||||||
|
pandora.UI.set('showFolder|items|' + folder.id, !data.collapsed);
|
||||||
|
pandora.resizeFolders();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//$sections.push(app.$ui.section[i]);
|
||||||
|
app.$ui.folderList[folder.id] = pandora.ui.folderList(folder.id)
|
||||||
|
.bindEventOnce({
|
||||||
|
init: function(event, data) {
|
||||||
|
Ox.print('init', i, counter)
|
||||||
|
if (++counter == 3) {
|
||||||
|
app.$ui.folder.forEach(function($folder) {
|
||||||
|
that.append($folder);
|
||||||
|
});
|
||||||
|
pandora.resizeFolders();
|
||||||
|
pandora.selectList(); //fixme: doesn't work
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(app.$ui.folder[i].$content);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
that.toggle = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
return that;
|
||||||
|
};
|
274
static/js/pandora/ui/foldersList.js
Normal file
274
static/js/pandora/ui/foldersList.js
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.folderList = function(id) {
|
||||||
|
var i = Ox.getPositionById(app.ui.sectionFolders[app.user.ui.section], id),
|
||||||
|
that;
|
||||||
|
if (app.user.ui.section == 'site') {
|
||||||
|
that = new Ox.TextList({
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
format: function() {
|
||||||
|
return $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.PATH + 'png/icon16.png'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
id: 'id',
|
||||||
|
operator: '+',
|
||||||
|
unique: true,
|
||||||
|
visible: true,
|
||||||
|
width: 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'title',
|
||||||
|
operator: '+',
|
||||||
|
visible: true,
|
||||||
|
width: app.user.ui.sidebarSize - 16
|
||||||
|
}
|
||||||
|
],
|
||||||
|
items: function(data, callback) {
|
||||||
|
var result = {data: {}};
|
||||||
|
if (!data.range) {
|
||||||
|
result.data.items = Ox.getObjectById(app.ui.sectionFolders.site, id).items.length;
|
||||||
|
} else {
|
||||||
|
result.data.items = Ox.getObjectById(app.ui.sectionFolders.site, id).items;
|
||||||
|
}
|
||||||
|
callback(result);
|
||||||
|
},
|
||||||
|
max: 1,
|
||||||
|
min: 1,
|
||||||
|
sort: [{key: '', operator: ''}]
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
select: function(event, data) {
|
||||||
|
// fixme: duplicated
|
||||||
|
$.each(app.$ui.folderList, function(id_, $list) {
|
||||||
|
id != id_ && $list.options('selected', []);
|
||||||
|
})
|
||||||
|
pandora.URL.set((id == 'admin' ? 'admin/' : '' ) + data.ids[0]);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (app.user.ui.section == 'items') {
|
||||||
|
that = new Ox.TextList({
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
format: function() {
|
||||||
|
return $('<img>').attr({
|
||||||
|
src: Ox.UI.PATH + 'png/icon16.png'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
id: 'user',
|
||||||
|
operator: '+',
|
||||||
|
visible: true,
|
||||||
|
width: 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: function(value) {
|
||||||
|
return value.split('/').join(': ');
|
||||||
|
},
|
||||||
|
id: 'id',
|
||||||
|
operator: '+',
|
||||||
|
unique: true,
|
||||||
|
visible: id == 'favorite',
|
||||||
|
width: app.user.ui.sidebarWidth - 88
|
||||||
|
},
|
||||||
|
{
|
||||||
|
editable: function(data) {
|
||||||
|
return data.user == app.user.username;
|
||||||
|
},
|
||||||
|
id: 'name',
|
||||||
|
input: {
|
||||||
|
autovalidate: pandora.ui.autovalidateListname
|
||||||
|
},
|
||||||
|
operator: '+',
|
||||||
|
visible: id != 'favorite',
|
||||||
|
width: app.user.ui.sidebarWidth - 88
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
id: 'items',
|
||||||
|
operator: '-',
|
||||||
|
visible: true,
|
||||||
|
width: 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
clickable: function(data) {
|
||||||
|
return data.type == 'smart';
|
||||||
|
},
|
||||||
|
format: function(value) {
|
||||||
|
return $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.getImagePath('symbolFind.svg')
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: '10px',
|
||||||
|
height: '10px',
|
||||||
|
padding: '3px 2px 1px 2px',
|
||||||
|
opacity: value == 'static' ? 0.1 : 1
|
||||||
|
});
|
||||||
|
},
|
||||||
|
id: 'type',
|
||||||
|
operator: '+',
|
||||||
|
visible: true,
|
||||||
|
width: 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
clickable: id == 'personal',
|
||||||
|
format: function(value) {
|
||||||
|
//var symbols = {private: 'Publish', public: 'Publish', featured: 'Star'};
|
||||||
|
return $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: Ox.UI.getImagePath(
|
||||||
|
'symbol' + (value == 'featured' ? 'Star' : 'Publish') + '.svg'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: '10px',
|
||||||
|
height: '10px',
|
||||||
|
padding: '3px 2px 1px 2px',
|
||||||
|
opacity: value == 'private' ? 0.1 : 1
|
||||||
|
})
|
||||||
|
},
|
||||||
|
id: 'status',
|
||||||
|
operator: '+',
|
||||||
|
visible: true,
|
||||||
|
width: 16
|
||||||
|
}
|
||||||
|
],
|
||||||
|
items: function(data, callback) {
|
||||||
|
var query;
|
||||||
|
if (id == 'personal') {
|
||||||
|
query = {conditions: [
|
||||||
|
{key: 'user', value: app.user.username, operator: '='},
|
||||||
|
{key: 'status', value: 'featured', operator: '!'}
|
||||||
|
], operator: '&'};
|
||||||
|
} else if (id == 'favorite') {
|
||||||
|
query = {conditions: [
|
||||||
|
{key: 'subscribed', value: true, operator: '='},
|
||||||
|
{key: 'status', value: 'featured', operator: '!'},
|
||||||
|
], operator: '&'};
|
||||||
|
} else if (id == 'featured') {
|
||||||
|
query = {conditions: [{key: 'status', value: 'featured', operator: '='}], operator: '&'};
|
||||||
|
}
|
||||||
|
return pandora.api.findLists($.extend(data, {
|
||||||
|
query: query
|
||||||
|
}), callback);
|
||||||
|
},
|
||||||
|
max: 1,
|
||||||
|
min: 0,
|
||||||
|
pageLength: 1000,
|
||||||
|
sort: [
|
||||||
|
{key: 'position', operator: '+'}
|
||||||
|
],
|
||||||
|
sortable: id == 'personal' || id == 'favorite' || app.user.level == 'admin'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: app.user.ui.sidebarWidth + 'px',
|
||||||
|
})
|
||||||
|
.bind({
|
||||||
|
dragenter: function(e) {
|
||||||
|
//Ox.print('DRAGENTER', e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
click: function(event, data) {
|
||||||
|
var $list = app.$ui.folderList[id];
|
||||||
|
if (data.key == 'type') {
|
||||||
|
app.$ui.filterDialog = ui.filterDialog().open();
|
||||||
|
} else if (data.key == 'status') {
|
||||||
|
pandora.api.editList({
|
||||||
|
id: data.id,
|
||||||
|
status: $list.value(data.id, data.key) == 'private' ? 'public' : 'private'
|
||||||
|
}, function(result) {
|
||||||
|
$list.value(result.data.id, 'status', result.data.status);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'delete': function(event, data) {
|
||||||
|
var $list = app.$ui.folderList[id];
|
||||||
|
app.user.ui.listQuery.conditions = [];
|
||||||
|
pandora.URL.set(pandora.Query.toString());
|
||||||
|
$list.options({selected: []});
|
||||||
|
if (id == 'personal') {
|
||||||
|
pandora.api.removeList({
|
||||||
|
id: data.ids[0]
|
||||||
|
}, function(result) {
|
||||||
|
// fixme: is this the best way to delete a ui preference?
|
||||||
|
delete app.user.ui.lists[data.ids[0]];
|
||||||
|
pandora.UI.set({lists: app.user.ui.lists});
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
$list.reloadList();
|
||||||
|
});
|
||||||
|
} else if (id == 'favorite') {
|
||||||
|
pandora.api.unsubscribeFromList({
|
||||||
|
id: data.ids[0]
|
||||||
|
}, function(result) {
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
$list.reloadList();
|
||||||
|
});
|
||||||
|
} else if (id == 'featured' && app.user.level == 'admin') {
|
||||||
|
pandora.api.editList({
|
||||||
|
id: data.ids[0],
|
||||||
|
status: 'public'
|
||||||
|
}, function(result) {
|
||||||
|
// fixme: duplicated
|
||||||
|
if (result.data.user == app.user.username || result.data.subscribed) {
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
app.$ui.folderList[
|
||||||
|
result.data.user == app.user.username ? 'personal' : 'favorite'
|
||||||
|
].reloadList();
|
||||||
|
}
|
||||||
|
$list.reloadList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
init: function(event, data) {
|
||||||
|
app.ui.sectionFolders[app.user.ui.section][i].items = data.items;
|
||||||
|
app.$ui.folder[i].$content.css({
|
||||||
|
height: data.items * 16 + 'px'
|
||||||
|
});
|
||||||
|
app.$ui.folderList[id].css({
|
||||||
|
height: data.items * 16 + 'px'
|
||||||
|
});
|
||||||
|
pandora.resizeFolders();
|
||||||
|
},
|
||||||
|
move: function(event, data) {
|
||||||
|
/*
|
||||||
|
data.ids.forEach(function(id, pos) {
|
||||||
|
app.user.ui.lists[id].position = pos;
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
pandora.api.sortLists({
|
||||||
|
section: id,
|
||||||
|
ids: data.ids
|
||||||
|
});
|
||||||
|
},
|
||||||
|
paste: function(event, data) {
|
||||||
|
app.$ui.list.triggerEvent('paste', data);
|
||||||
|
},
|
||||||
|
select: function(event, data) {
|
||||||
|
if (data.ids.length) {
|
||||||
|
$.each(app.$ui.folderList, function(id_, $list) {
|
||||||
|
id != id_ && $list.options('selected', []);
|
||||||
|
})
|
||||||
|
pandora.URL.set('?find=list:' + data.ids[0]);
|
||||||
|
} else {
|
||||||
|
pandora.URL.set('?find=');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submit: function(event, data) {
|
||||||
|
data_ = {id: data.id};
|
||||||
|
data_[data.key] = data.value;
|
||||||
|
pandora.api.editList(data_, function(result) {
|
||||||
|
if (result.data.id != data.id) {
|
||||||
|
app.$ui.folderList[id].value(data.id, 'name', result.data.name);
|
||||||
|
app.$ui.folderList[id].value(data.id, 'id', result.data.id);
|
||||||
|
pandora.URL.set('?find=list:' + result.data.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
170
static/js/pandora/ui/group.js
Normal file
170
static/js/pandora/ui/group.js
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.group = function(id, query) {
|
||||||
|
//Ox.print('group', id, query);
|
||||||
|
/*
|
||||||
|
query && query.conditions.length && alert($.map(query.conditions, function(v) {
|
||||||
|
return v.value;
|
||||||
|
}));
|
||||||
|
*/
|
||||||
|
//alert(id + ' ' + JSON.stringify(pandora.Query.toObject(id)))
|
||||||
|
var i = app.user.ui.groups.indexOf(id),
|
||||||
|
panelWidth = app.$ui.document.width() - (app.user.ui.showSidebar * app.user.ui.sidebarSize) - 1,
|
||||||
|
title = Ox.getObjectById(app.config.groups, id).title,
|
||||||
|
width = pandora.getGroupWidth(i, panelWidth),
|
||||||
|
that = new Ox.TextList({
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
id: 'name',
|
||||||
|
operator: id == 'year' ? '-' : '+',
|
||||||
|
title: title,
|
||||||
|
unique: true,
|
||||||
|
visible: true,
|
||||||
|
width: width.column
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
id: 'items',
|
||||||
|
operator: '-',
|
||||||
|
title: '#',
|
||||||
|
visible: true,
|
||||||
|
width: 40
|
||||||
|
}
|
||||||
|
],
|
||||||
|
columnsVisible: true,
|
||||||
|
id: 'group_' + id,
|
||||||
|
items: function(data, callback) {
|
||||||
|
//Ox.print('sending request', data)
|
||||||
|
delete data.keys;
|
||||||
|
//alert(id + " pandora.Query.toObject " + JSON.stringify(pandora.Query.toObject(id)) + ' ' + JSON.stringify(data))
|
||||||
|
return pandora.api.find($.extend(data, {
|
||||||
|
group: id,
|
||||||
|
query: pandora.Query.toObject(id)
|
||||||
|
}), callback);
|
||||||
|
},
|
||||||
|
scrollbarVisible: true,
|
||||||
|
selected: query ? $.map(query.conditions, function(v) {
|
||||||
|
return v.value;
|
||||||
|
}) : [],
|
||||||
|
sort: [
|
||||||
|
{
|
||||||
|
key: id == 'year' ? 'name' : 'items',
|
||||||
|
operator: '-'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
paste: function(event, data) {
|
||||||
|
app.$ui.list.triggerEvent('paste', data);
|
||||||
|
},
|
||||||
|
select: function(event, data) {
|
||||||
|
var group = app.ui.groups[i],
|
||||||
|
query;
|
||||||
|
app.ui.groups[i].query.conditions = $.map(data.ids, function(v) {
|
||||||
|
return {
|
||||||
|
key: id,
|
||||||
|
value: v,
|
||||||
|
operator: '='
|
||||||
|
};
|
||||||
|
});
|
||||||
|
reloadGroups(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
new Ox.Select({
|
||||||
|
items: $.map(app.config.groups, function(v) {
|
||||||
|
return {
|
||||||
|
checked: v.id == id,
|
||||||
|
id: v.id,
|
||||||
|
title: v.title
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
max: 1,
|
||||||
|
min: 1,
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent('change', function(event, data) {
|
||||||
|
var id_ = data.selected[0].id,
|
||||||
|
i_ = app.user.ui.groups.indexOf(id_);
|
||||||
|
if (i_ == -1) {
|
||||||
|
// new group was not part of old group set
|
||||||
|
if (app.ui.groups[i].query.conditions.length) {
|
||||||
|
// if group with selection gets replaced, reload
|
||||||
|
app.ui.groups[i].query.conditions = [];
|
||||||
|
reloadGroups(i);
|
||||||
|
}
|
||||||
|
app.ui.groups[i] = getGroupObject(id_);
|
||||||
|
app.user.ui.groups[i] = id_;
|
||||||
|
pandora.UI.set({groups: app.user.ui.groups});
|
||||||
|
replaceGroup(i, id_);
|
||||||
|
} else {
|
||||||
|
// swap two existing groups
|
||||||
|
var group = $.extend({}, app.ui.groups[i]);
|
||||||
|
app.ui.groups[i] = app.ui.groups[i_];
|
||||||
|
app.ui.groups[i_] = group;
|
||||||
|
app.user.ui.groups[i] = id_;
|
||||||
|
app.user.ui.groups[i_] = id;
|
||||||
|
pandora.UI.set({groups: app.user.ui.groups});
|
||||||
|
replaceGroup(i, id_, app.ui.groups[i].query);
|
||||||
|
replaceGroup(i_, id, app.ui.groups[i_].query);
|
||||||
|
}
|
||||||
|
function replaceGroup(i, id, query) {
|
||||||
|
// if query is passed, selected items will be derived from it
|
||||||
|
var isOuter = i % 4 == 0;
|
||||||
|
app.$ui[isOuter ? 'browser' : 'groupsInnerPanel'].replaceElement(
|
||||||
|
isOuter ? i / 2 : i - 1,
|
||||||
|
app.$ui.groups[i] = pandora.ui.group(id, query)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo(that.$bar.$element);
|
||||||
|
if (!query) {
|
||||||
|
// if query is set, group object has already been taken care of
|
||||||
|
app.ui.groups[i] = getGroupObject(id);
|
||||||
|
}
|
||||||
|
function getGroupObject(id) {
|
||||||
|
var i = app.user.ui.groups.indexOf(id),
|
||||||
|
title = Ox.getObjectById(app.config.groups, id).title,
|
||||||
|
width = pandora.getGroupWidth(i, panelWidth);
|
||||||
|
return {
|
||||||
|
id: id,
|
||||||
|
element: that,
|
||||||
|
query: {
|
||||||
|
conditions: [],
|
||||||
|
operator: '|'
|
||||||
|
},
|
||||||
|
size: width.list,
|
||||||
|
title: title
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
||||||
|
pandora.ui.groups = function() {
|
||||||
|
var $groups = [];
|
||||||
|
app.ui.groups = [];
|
||||||
|
app.user.ui.groups.forEach(function(id, i) {
|
||||||
|
$groups[i] = pandora.ui.group(id);
|
||||||
|
});
|
||||||
|
return $groups;
|
||||||
|
};
|
||||||
|
|
||||||
|
pandora.ui.groupsInnerPanel = function() {
|
||||||
|
var that = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: app.$ui.groups[1],
|
||||||
|
size: app.ui.groups[1].size
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.groups[2],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.groups[3],
|
||||||
|
size: app.ui.groups[3].size
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'horizontal'
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
50
static/js/pandora/ui/info.js
Normal file
50
static/js/pandora/ui/info.js
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.info = function() {
|
||||||
|
var that = new Ox.Element()
|
||||||
|
.append(
|
||||||
|
app.$ui.infoStill = new Ox.Element()
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
height: '96px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
app.$ui.infoTimeline = new Ox.Element('<img>')
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
bottom: 0,
|
||||||
|
height: '16px',
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.bindEvent({
|
||||||
|
toggle: function(event, data) {
|
||||||
|
UI.set({showInfo: !data.collapsed});
|
||||||
|
pandora.resizeFolders();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(app.user.ui.item) {
|
||||||
|
pandora.api.getItem(app.user.ui.item, function(result) {
|
||||||
|
app.ui.infoRatio = result.data.item.stream.aspectRatio;
|
||||||
|
var width = that.width() || 256,
|
||||||
|
height = width / app.ui.infoRatio + 16;
|
||||||
|
app.$ui.infoStill.removeElement();
|
||||||
|
app.$ui.infoStill = pandora.ui.flipbook(app.user.ui.item)
|
||||||
|
.appendTo(that.$element);
|
||||||
|
app.$ui.infoStill.css({
|
||||||
|
'height': (height-16) + 'px'
|
||||||
|
});
|
||||||
|
that.css({
|
||||||
|
height: height + 'px'
|
||||||
|
});
|
||||||
|
pandora.resizeFolders();
|
||||||
|
!app.user.ui.showInfo && app.$ui.leftPanel.css({bottom: -height});
|
||||||
|
app.$ui.leftPanel.size(2, height );
|
||||||
|
});
|
||||||
|
app.$ui.infoTimeline.attr('src', '/'+app.user.ui.item+'/timeline.16.png')
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
202
static/js/pandora/ui/item.js
Normal file
202
static/js/pandora/ui/item.js
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.item = function() {
|
||||||
|
var that;
|
||||||
|
if (app.user.ui.itemView == 'info' || app.user.ui.itemView == 'files') {
|
||||||
|
that = new Ox.Element();
|
||||||
|
} else if (app.user.ui.itemView == 'player') {
|
||||||
|
that = new Ox.Element();
|
||||||
|
} else if (app.user.ui.itemView == 'timeline') {
|
||||||
|
that = new Ox.Element();
|
||||||
|
}
|
||||||
|
pandora.api.getItem(app.user.ui.item, function(result) {
|
||||||
|
if (app.user.ui.itemView == 'info') {
|
||||||
|
//Ox.print('result.data.item', result.data.item)
|
||||||
|
if (app.user.level == 'admin') {
|
||||||
|
var $form,
|
||||||
|
$edit = new Ox.Element()
|
||||||
|
.append($form = new Ox.FormElementGroup({
|
||||||
|
elements: Ox.map(app.config.itemKeys, function(key) {
|
||||||
|
return new Ox.Input({
|
||||||
|
id: key.id,
|
||||||
|
label: key.title,
|
||||||
|
labelWidth: 100,
|
||||||
|
value: result.data.item[key.id],
|
||||||
|
type: 'text',
|
||||||
|
width: 500
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
separators: [
|
||||||
|
{title: '', width: 0}
|
||||||
|
]
|
||||||
|
}))
|
||||||
|
.append(new Ox.Button({
|
||||||
|
title: 'Save',
|
||||||
|
type: 'text'
|
||||||
|
}).bindEvent({
|
||||||
|
click: function(event, data) {
|
||||||
|
var values = $form.value();
|
||||||
|
var changed = {};
|
||||||
|
Ox.map(app.config.itemKeys, function(key, i) {
|
||||||
|
if(values[i] && values[i] != ''+result.data.item[key.id]) {
|
||||||
|
if(Ox.isArray(key.type) && key.type[0] == 'string')
|
||||||
|
changed[key.id] = values[i].split(', ');
|
||||||
|
else
|
||||||
|
changed[key.id] = values[i];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(changed) {
|
||||||
|
pandora.api.editItem(Ox.extend(changed, {id: app.user.ui.item}), function(result) {
|
||||||
|
//fixme just reload parts that need reloading
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
app.$ui.contentPanel.replaceElement(1, app.$ui.item = $edit);
|
||||||
|
} else {
|
||||||
|
$.get('/static/html/itemInfo.html', {}, function(template) {
|
||||||
|
//Ox.print(template);
|
||||||
|
app.$ui.contentPanel.replaceElement(1,
|
||||||
|
app.$ui.item = new Ox.Element()
|
||||||
|
.append($.tmpl(template, result.data.item))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (app.user.ui.itemView == 'player') {
|
||||||
|
var video = result.data.item.stream,
|
||||||
|
subtitles = result.data.item.layers.subtitles,
|
||||||
|
format = $.support.video.supportedFormat(video.formats);
|
||||||
|
video.height = video.profiles[0]
|
||||||
|
video.width = parseInt(video.height * video.aspectRatio / 2) * 2;
|
||||||
|
video.url = video.baseUrl + '/' + video.height + 'p.' + format;
|
||||||
|
app.$ui.contentPanel.replaceElement(1, app.$ui.player = new Ox.VideoPanelPlayer({
|
||||||
|
annotationsSize: app.user.ui.annotationsSize,
|
||||||
|
duration: video.duration,
|
||||||
|
height: app.$ui.contentPanel.size(1),
|
||||||
|
position: app.user.ui.videoPosition[app.user.ui.item] || 0,
|
||||||
|
showAnnotations: app.user.ui.showAnnotations,
|
||||||
|
showControls: app.user.ui.showControls,
|
||||||
|
subtitles: subtitles,
|
||||||
|
videoHeight: video.height,
|
||||||
|
videoId: app.user.ui.item,
|
||||||
|
videoWidth: video.width,
|
||||||
|
videoSize: app.user.ui.videoScreen,
|
||||||
|
videoURL: video.url,
|
||||||
|
width: app.$ui.document.width() - app.$ui.mainPanel.size(0) - 1
|
||||||
|
}).bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
// showAnnotations, showControls, videoScreen
|
||||||
|
pandora.UI.set('videoSize' in data ? {
|
||||||
|
videoScreen: data.videoSize
|
||||||
|
} : data);
|
||||||
|
},
|
||||||
|
enterfullscreen: pandora.enterFullscreen,
|
||||||
|
exitfullscreen: pandora.exitFullscreen,
|
||||||
|
resize: function(event, data) {
|
||||||
|
app.$ui.player.options({
|
||||||
|
height: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
} else if (app.user.ui.itemView == 'timeline') {
|
||||||
|
var layers = [],
|
||||||
|
video = result.data.item.stream,
|
||||||
|
cuts = result.data.item.cuts || {},
|
||||||
|
format = $.support.video.supportedFormat(video.formats);
|
||||||
|
subtitles = result.data.item.layers.subtitles;
|
||||||
|
video.height = video.profiles[0];
|
||||||
|
video.width = parseInt(video.height * video.aspectRatio / 2) * 2;
|
||||||
|
video.url = video.baseUrl + '/' + video.height + 'p.' + format;
|
||||||
|
$.each(app.config.layers, function(i, layer) {
|
||||||
|
layers[i] = $.extend({}, layer, {items: result.data.item.layers[layer.id]});
|
||||||
|
});
|
||||||
|
app.$ui.contentPanel.replaceElement(1, app.$ui.editor = new Ox.VideoEditor({
|
||||||
|
annotationsSize: app.user.ui.annotationsSize,
|
||||||
|
cuts: cuts,
|
||||||
|
duration: video.duration,
|
||||||
|
find: '',
|
||||||
|
getFrameURL: function(position) {
|
||||||
|
return '/' + app.user.ui.item + '/frame/' + video.width.toString() + '/' + position.toString() + '.jpg'
|
||||||
|
},
|
||||||
|
getLargeTimelineImageURL: function(i) {
|
||||||
|
return '/' + app.user.ui.item + '/timelines/timeline.64.' + i + '.png';
|
||||||
|
},
|
||||||
|
getSmallTimelineImageURL: function(i) {
|
||||||
|
return '/' + app.user.ui.item + '/timelines/timeline.16.' + i + '.png';
|
||||||
|
},
|
||||||
|
height: app.$ui.contentPanel.size(1),
|
||||||
|
id: 'editor',
|
||||||
|
'in': 0,
|
||||||
|
layers: layers,
|
||||||
|
out: 0,
|
||||||
|
position: app.user.ui.videoPosition[app.user.ui.item] || 0,
|
||||||
|
posterFrame: parseInt(video.duration / 2),
|
||||||
|
showAnnotations: app.user.ui.showAnnotations,
|
||||||
|
showLargeTimeline: true,
|
||||||
|
// fixme: layers have value, subtitles has text?
|
||||||
|
subtitles: subtitles.map(function(subtitle) {
|
||||||
|
return {'in': subtitle['in'], out: subtitle.out, text: subtitle.value};
|
||||||
|
}),
|
||||||
|
videoHeight: video.height,
|
||||||
|
videoId: app.user.ui.item,
|
||||||
|
videoWidth: video.width,
|
||||||
|
videoSize: app.user.ui.videoSize,
|
||||||
|
video: video.url,
|
||||||
|
width: app.$ui.document.width() - app.$ui.mainPanel.size(0) - 1
|
||||||
|
}).bindEvent({
|
||||||
|
resize: function(event, data) {
|
||||||
|
app.$ui.editor.options({
|
||||||
|
height: data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
togglesize: function(event, data) {
|
||||||
|
pandora.UI.set({videoSize: data.size});
|
||||||
|
},
|
||||||
|
addAnnotation: function(event, data) {
|
||||||
|
Ox.print('addAnnotation', data);
|
||||||
|
data.item = app.user.ui.item;
|
||||||
|
data.value = 'Click to edit';
|
||||||
|
pandora.api.addAnnotation(data, function(result) {
|
||||||
|
app.$ui.editor.addAnnotation(data.layer, result.data);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
removeAnnotations: function(event, data) {
|
||||||
|
pandora.api.removeAnnotations(data, function(result) {
|
||||||
|
//fixme: check for errors
|
||||||
|
app.$ui.editor.removeAnnotations(data.layer, data.ids);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateAnnotation: function(event, data) {
|
||||||
|
//fixme: check that edit was successfull
|
||||||
|
Ox.print('updateAnnotation', data);
|
||||||
|
pandora.api.editAnnotation(data);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
that.bindEvent('resize', function(event, data) {
|
||||||
|
//Ox.print('resize item', data)
|
||||||
|
app.$ui.editor.options({
|
||||||
|
height: data
|
||||||
|
});
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
app.$ui.rightPanel.bindEvent('resize', function(event, data) {
|
||||||
|
Ox.print('... rightPanel resize', data, app.$ui.timelinePanel.size(1))
|
||||||
|
app.$ui.editor.options({
|
||||||
|
width: data - app.$ui.timelinePanel.size(1) - 1
|
||||||
|
});
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
} else if (app.user.ui.itemView == 'files') {
|
||||||
|
app.$ui.contentPanel.replaceElement(1,
|
||||||
|
app.$ui.item = new Ox.FilesView({
|
||||||
|
id: result.data.item.id
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
var director = result.data.item.director?' ('+result.data.item.director.join(', ')+')':'';
|
||||||
|
app.$ui.total.html(result.data.item.title + director);
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
53
static/js/pandora/ui/leftPanel.js
Normal file
53
static/js/pandora/ui/leftPanel.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.leftPanel = function() {
|
||||||
|
var that = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: app.$ui.sectionbar = pandora.ui.sectionbar('buttons'),
|
||||||
|
size: 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.folders = pandora.ui.folders()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
collapsed: !app.user.ui.showInfo,
|
||||||
|
collapsible: true,
|
||||||
|
element: app.$ui.info = pandora.ui.info(),
|
||||||
|
size: app.user.ui.sidebarSize / app.ui.infoRatio + 16
|
||||||
|
}
|
||||||
|
],
|
||||||
|
id: 'leftPanel',
|
||||||
|
orientation: 'vertical'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
resize: function(event, data) {
|
||||||
|
var infoSize = Math.round(data / app.ui.infoRatio) + 16;
|
||||||
|
app.user.ui.sidebarSize = data;
|
||||||
|
if (data < app.ui.sectionButtonsWidth && app.$ui.sectionButtons) {
|
||||||
|
app.$ui.sectionButtons.removeElement();
|
||||||
|
delete app.$ui.sectionButtons;
|
||||||
|
app.$ui.sectionbar.append(app.$ui.sectionSelect = pandora.ui.sectionSelect());
|
||||||
|
} else if (data >= app.ui.sectionButtonsWidth && app.$ui.sectionSelect) {
|
||||||
|
app.$ui.sectionSelect.removeElement();
|
||||||
|
delete app.$ui.sectionSelect;
|
||||||
|
app.$ui.sectionbar.append(app.$ui.sectionButtons = pandora.ui.sectionButtons());
|
||||||
|
}
|
||||||
|
!app.user.ui.showInfo && app.$ui.leftPanel.css({bottom: -infoSize});
|
||||||
|
app.$ui.leftPanel.size(2, infoSize);
|
||||||
|
pandora.resizeFolders();
|
||||||
|
},
|
||||||
|
resizeend: function(event, data) {
|
||||||
|
pandora.UI.set({sidebarSize: data});
|
||||||
|
},
|
||||||
|
toggle: function(event, data) {
|
||||||
|
pandora.UI.set({showSidebar: !data.collapsed});
|
||||||
|
if (data.collapsed) {
|
||||||
|
$.each(app.$ui.folderList, function(k, $list) {
|
||||||
|
$list.loseFocus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
425
static/js/pandora/ui/list.js
Normal file
425
static/js/pandora/ui/list.js
Normal file
|
@ -0,0 +1,425 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.list = function(view) { // fixme: remove view argument
|
||||||
|
var that, $map;
|
||||||
|
//Ox.print('constructList', view);
|
||||||
|
if (view == 'list') {
|
||||||
|
/*
|
||||||
|
keys = Ox.unique($.merge(
|
||||||
|
$.map(app.user.ui.lists[app.user.ui.list].columns, function(id) {
|
||||||
|
return Ox.getObjectById(app.config.sortKeys, id);
|
||||||
|
}),
|
||||||
|
app.config.sortKeys
|
||||||
|
));
|
||||||
|
Ox.print('$$$$', keys)
|
||||||
|
*/
|
||||||
|
that = new Ox.TextList({
|
||||||
|
columns: $.map(app.ui.sortKeys, function(key, i) {
|
||||||
|
var position = app.user.ui.lists[app.user.ui.list].columns.indexOf(key.id);
|
||||||
|
return {
|
||||||
|
align: ['string', 'text'].indexOf(
|
||||||
|
Ox.isArray(key.type) ? key.type[0]: key.type
|
||||||
|
) > -1 ? 'left' : 'right',
|
||||||
|
defaultWidth: key.columnWidth,
|
||||||
|
format: key.format,
|
||||||
|
id: key.id,
|
||||||
|
operator: pandora.getSortOperator(key.id),
|
||||||
|
position: position,
|
||||||
|
removable: !key.columnRequired,
|
||||||
|
title: key.title,
|
||||||
|
type: key.type,
|
||||||
|
unique: key.id == 'id',
|
||||||
|
visible: position > -1,
|
||||||
|
width: app.user.ui.lists[app.user.ui.list].columnWidth[key.id] || key.columnWidth
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
columnsMovable: true,
|
||||||
|
columnsRemovable: true,
|
||||||
|
columnsResizable: true,
|
||||||
|
columnsVisible: true,
|
||||||
|
id: 'list',
|
||||||
|
items: function(data, callback) {
|
||||||
|
//Ox.print('data, pandora.Query.toObject', data, pandora.Query.toObject())
|
||||||
|
pandora.api.find($.extend(data, {
|
||||||
|
query: pandora.Query.toObject()
|
||||||
|
}), callback);
|
||||||
|
},
|
||||||
|
scrollbarVisible: true,
|
||||||
|
sort: app.user.ui.lists[app.user.ui.list].sort
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
columnchange: function(event, data) {
|
||||||
|
var columnWidth = {}
|
||||||
|
pandora.UI.set(['lists', app.user.ui.list, 'columns'].join('|'), data.ids);
|
||||||
|
/*
|
||||||
|
data.ids.forEach(function(id) {
|
||||||
|
columnWidth[id] =
|
||||||
|
app.user.ui.lists[app.user.ui.list].columnWidth[id] ||
|
||||||
|
Ox.getObjectById(app.ui.sortKeys, id).width
|
||||||
|
});
|
||||||
|
pandora.UI.set(['lists', app.user.ui.list, 'columnWidth'].join('|'), columnWidth);
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
columnresize: function(event, data) {
|
||||||
|
pandora.UI.set(['lists', app.user.ui.list, 'columnWidth', data.id].join('|'), data.width);
|
||||||
|
},
|
||||||
|
resize: function(event, data) { // this is the resize event of the split panel
|
||||||
|
that.size();
|
||||||
|
},
|
||||||
|
sort: function(event, data) {
|
||||||
|
pandora.UI.set(['lists', app.user.ui.list, 'sort'].join('|'), [data]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (view == 'icons') {
|
||||||
|
that = new Ox.IconList({
|
||||||
|
id: 'list',
|
||||||
|
item: function(data, sort, size) {
|
||||||
|
var ratio = data.poster.width / data.poster.height;
|
||||||
|
size = size || 128;
|
||||||
|
return {
|
||||||
|
height: ratio <= 1 ? size : size / ratio,
|
||||||
|
id: data['id'],
|
||||||
|
info: data[['title', 'director'].indexOf(sort[0].key) > -1 ? 'year' : sort[0].key],
|
||||||
|
title: data.title + (data.director.length ? ' (' + data.director.join(', ') + ')' : ''),
|
||||||
|
url: data.poster.url.replace(/jpg/, size + '.jpg'),
|
||||||
|
width: ratio >= 1 ? size : size * ratio
|
||||||
|
};
|
||||||
|
},
|
||||||
|
items: function(data, callback) {
|
||||||
|
//Ox.print('data, pandora.Query.toObject', data, pandora.Query.toObject())
|
||||||
|
pandora.api.find($.extend(data, {
|
||||||
|
query: pandora.Query.toObject()
|
||||||
|
}), callback);
|
||||||
|
},
|
||||||
|
keys: ['director', 'id', 'poster', 'title', 'year'],
|
||||||
|
size: 128,
|
||||||
|
sort: app.user.ui.lists[app.user.ui.list].sort,
|
||||||
|
unique: 'id'
|
||||||
|
})
|
||||||
|
} else if (view == 'map') {
|
||||||
|
that = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: new Ox.Toolbar({
|
||||||
|
orientation: 'horizontal',
|
||||||
|
size: 24
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
app.$ui.findMapInput = new Ox.Input({
|
||||||
|
clear: true,
|
||||||
|
id: 'findMapInput',
|
||||||
|
placeholder: 'Find on Map',
|
||||||
|
width: 192
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'right',
|
||||||
|
margin: '4px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
submit: function(event, data) {
|
||||||
|
app.$ui.map.find(data.value, function(data) {
|
||||||
|
app.$ui.mapStatusbar.html(data.geoname + ' ' + JSON.stringify(data.points))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
),
|
||||||
|
size: 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.map = new Ox.Map({
|
||||||
|
places: [
|
||||||
|
{
|
||||||
|
geoname: 'Beirut, Lebanon',
|
||||||
|
name: 'Beirut',
|
||||||
|
points: {
|
||||||
|
'center': [33.8886284, 35.4954794],
|
||||||
|
'northeast': [33.8978909, 35.5114868],
|
||||||
|
'southwest': [33.8793659, 35.479472]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
geoname: 'Berlin, Germany',
|
||||||
|
name: 'Berlin',
|
||||||
|
points: {
|
||||||
|
'center': [52.506701, 13.4246065],
|
||||||
|
'northeast': [52.675323, 13.760909],
|
||||||
|
'southwest': [52.338079, 13.088304]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
geoname: 'Mumbai, Maharashtra, India',
|
||||||
|
name: 'Bombay',
|
||||||
|
points: {
|
||||||
|
'center': [19.07871865, 72.8778187],
|
||||||
|
'northeast': [19.2695223, 72.9806562],
|
||||||
|
'southwest': [18.887915, 72.7749812]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
select: function(event, data) {
|
||||||
|
app.$ui.mapStatusbar.html(data.geoname + ' ' + JSON.stringify(data.points))
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
id: 'map',
|
||||||
|
size: 'auto'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.mapStatusbar = new Ox.Toolbar({
|
||||||
|
orientation: 'horizontal',
|
||||||
|
size: 16
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
fontSize: '9px',
|
||||||
|
padding: '2px 4px 0 0',
|
||||||
|
textAlign: 'right'
|
||||||
|
}),
|
||||||
|
size: 16
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'vertical'
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: new Ox.Element(),
|
||||||
|
id: 'place',
|
||||||
|
size: 128 + 16 + 12
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'horizontal'
|
||||||
|
})
|
||||||
|
.bindEvent('resize', function() {
|
||||||
|
app.$ui.map.resize();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$list = new Ox.Element('<div>')
|
||||||
|
.css({
|
||||||
|
width: '100px',
|
||||||
|
height: '100px',
|
||||||
|
background: 'red'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
['list', 'icons'].indexOf(view) > -1 && that.bind({
|
||||||
|
dragstart: function(e) {
|
||||||
|
app.$ui.folderList.forEach(function($list, i) {
|
||||||
|
$list.addClass('OxDrop');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
dragend: function(e) {
|
||||||
|
app.$ui.folderList.forEach(function($list, i) {
|
||||||
|
$list.removeClass('OxDrop');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}).bindEvent({
|
||||||
|
closepreview: function(event, data) {
|
||||||
|
app.$ui.previewDialog.close();
|
||||||
|
delete app.$ui.previewDialog;
|
||||||
|
},
|
||||||
|
copy: function(event, data) {
|
||||||
|
Ox.Clipboard.copy({
|
||||||
|
items: data.ids,
|
||||||
|
text: $.map(data.ids, function(id) {
|
||||||
|
return app.$ui.list.value(id, 'title');
|
||||||
|
}).join('\n')
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'delete': function(event, data) {
|
||||||
|
getListData().editable && pandora.api.removeListItems({
|
||||||
|
list: app.user.ui.list,
|
||||||
|
items: data.ids
|
||||||
|
}, reloadList);
|
||||||
|
},
|
||||||
|
init: function(event, data) {
|
||||||
|
app.$ui.total.html(pandora.ui.status('total', data));
|
||||||
|
data = [];
|
||||||
|
$.each(app.config.totals, function(i, v) {
|
||||||
|
data[v.id] = 0;
|
||||||
|
});
|
||||||
|
app.$ui.selected.html(pandora.ui.status('selected', data));
|
||||||
|
},
|
||||||
|
open: function(event, data) {
|
||||||
|
var id = data.ids[0],
|
||||||
|
title = that.value(id, 'title');
|
||||||
|
pandora.URL.set(title, id);
|
||||||
|
},
|
||||||
|
openpreview: function(event, data) {
|
||||||
|
app.requests.preview && pandora.api.cancel(app.requests.preview);
|
||||||
|
app.requests.preview = pandora.api.find({
|
||||||
|
keys: ['director', 'id', 'poster', 'title'],
|
||||||
|
query: {
|
||||||
|
conditions: $.map(data.ids, function(id, i) {
|
||||||
|
return {
|
||||||
|
key: 'id',
|
||||||
|
value: id,
|
||||||
|
operator: '='
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
operator: '|'
|
||||||
|
}
|
||||||
|
}, function(result) {
|
||||||
|
var documentHeight = app.$ui.document.height(),
|
||||||
|
item = result.data.items[0],
|
||||||
|
title = item.title + (item.director ? ' (' + item.director + ')' : ''),
|
||||||
|
dialogHeight = documentHeight - 100,
|
||||||
|
dialogWidth;
|
||||||
|
app.ui.previewRatio = item.poster.width / item.poster.height,
|
||||||
|
dialogWidth = parseInt((dialogHeight - 48) * app.ui.previewRatio);
|
||||||
|
if ('previewDialog' in app.$ui) {
|
||||||
|
app.$ui.previewDialog.options({
|
||||||
|
title: title
|
||||||
|
});
|
||||||
|
app.$ui.previewImage.animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 100, function() {
|
||||||
|
app.$ui.previewDialog.size(dialogWidth, dialogHeight, function() {
|
||||||
|
app.$ui.previewImage
|
||||||
|
.attr({
|
||||||
|
src: item.poster.url
|
||||||
|
})
|
||||||
|
.one('load', function() {
|
||||||
|
app.$ui.previewImage
|
||||||
|
.css({
|
||||||
|
width: dialogWidth + 'px',
|
||||||
|
height: (dialogHeight - 48 - 2) + 'px', // fixme: why -2 ?
|
||||||
|
opacity: 0
|
||||||
|
})
|
||||||
|
.animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//Ox.print(app.$ui.document.height(), dialogWidth, 'x', dialogHeight, dialogWidth / (dialogHeight - 48), item.poster.width, 'x', item.poster.height, item.poster.width / item.poster.height)
|
||||||
|
} else {
|
||||||
|
app.$ui.previewImage = $('<img>')
|
||||||
|
.attr({
|
||||||
|
src: item.poster.url
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
width: dialogWidth + 'px',
|
||||||
|
height: (dialogHeight - 48 - 2) + 'px', // fixme: why -2 ?
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
margin: 'auto',
|
||||||
|
});
|
||||||
|
app.$ui.previewDialog = new Ox.Dialog({
|
||||||
|
buttons: [
|
||||||
|
new Ox.Button({
|
||||||
|
title: 'Close',
|
||||||
|
}).bindEvent({
|
||||||
|
click: function() {
|
||||||
|
app.$ui.previewDialog.close();
|
||||||
|
delete app.$ui.previewDialog;
|
||||||
|
app.$ui.list.closePreview();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
content: app.$ui.previewImage,
|
||||||
|
height: dialogHeight,
|
||||||
|
id: 'previewDialog',
|
||||||
|
minHeight: app.ui.previewRatio >= 1 ? 128 / app.ui.previewRatio + 48 : 176,
|
||||||
|
minWidth: app.ui.previewRatio >= 1 ? 128 : 176 * app.ui.previewRatio,
|
||||||
|
padding: 0,
|
||||||
|
title: title,
|
||||||
|
width: dialogWidth
|
||||||
|
})
|
||||||
|
.bindEvent('resize', function(event, data) {
|
||||||
|
var dialogRatio = data.width / (data.height - 48),
|
||||||
|
height, width;
|
||||||
|
if (dialogRatio < app.ui.previewRatio) {
|
||||||
|
width = data.width;
|
||||||
|
height = width / app.ui.previewRatio;
|
||||||
|
} else {
|
||||||
|
height = (data.height - 48 - 2);
|
||||||
|
width = height * app.ui.previewRatio;
|
||||||
|
}
|
||||||
|
app.$ui.previewImage.css({
|
||||||
|
width: width + 'px',
|
||||||
|
height: height + 'px', // fixme: why -2 ?
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.open();
|
||||||
|
//app.$ui.previewImage = $image;
|
||||||
|
//Ox.print(app.$document.height(), dialogWidth, 'x', dialogHeight, dialogWidth / (dialogHeight - 48), item.poster.width, 'x', item.poster.height, item.poster.width / item.poster.height)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
paste: function(event, data) {
|
||||||
|
data.items && getListData().editable && pandora.api.addListItems({
|
||||||
|
list: app.user.ui.list,
|
||||||
|
items: data.items
|
||||||
|
}, reloadList);
|
||||||
|
},
|
||||||
|
select: function(event, data) {
|
||||||
|
var $still, $timeline;
|
||||||
|
app.ui.selectedMovies = data.ids;
|
||||||
|
if (data.ids.length) {
|
||||||
|
app.$ui.mainMenu.enableItem('copy');
|
||||||
|
app.$ui.mainMenu.enableItem('openmovie');
|
||||||
|
} else {
|
||||||
|
app.$ui.mainMenu.disableItem('copy');
|
||||||
|
app.$ui.mainMenu.disableItem('openmovie');
|
||||||
|
}
|
||||||
|
if (data.ids.length == 1) {
|
||||||
|
pandora.api.getItem(data.ids[0], function(result) {
|
||||||
|
app.ui.infoRatio = result.data.item.stream.aspectRatio;
|
||||||
|
var height = app.$ui.info.width() / app.ui.infoRatio + 16;
|
||||||
|
if(app.$ui.infoStill) app.$ui.infoStill.removeElement();
|
||||||
|
app.$ui.infoStill = pandora.ui.flipbook(data.ids[0])
|
||||||
|
.appendTo(app.$ui.info.$element);
|
||||||
|
app.$ui.infoStill.css({
|
||||||
|
'height': (height - 16) + 'px'
|
||||||
|
});
|
||||||
|
!app.user.ui.showInfo && app.$ui.leftPanel.css({bottom: -height});
|
||||||
|
app.$ui.leftPanel.size(2, height);
|
||||||
|
app.$ui.info.animate({
|
||||||
|
height: height + 'px'
|
||||||
|
}, 250, function() {
|
||||||
|
pandora.resizeFolders();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
app.$ui.infoTimeline.attr('src', '/'+data.ids[0]+'/timeline.16.png')
|
||||||
|
}
|
||||||
|
pandora.api.find({
|
||||||
|
query: {
|
||||||
|
conditions: $.map(data.ids, function(id, i) {
|
||||||
|
return {
|
||||||
|
key: 'id',
|
||||||
|
value: id,
|
||||||
|
operator: '='
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
operator: '|'
|
||||||
|
}
|
||||||
|
}, function(result) {
|
||||||
|
app.$ui.selected.html(pandora.ui.status('selected', result.data));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
sort: function(event, data) {
|
||||||
|
/* some magic has already set user.ui.sort
|
||||||
|
Ox.print(':', user.ui.sort[0])
|
||||||
|
if (data.key != user.ui.sort[0].key) {
|
||||||
|
app.$ui.mainMenu.checkItem('sort_sortmovies_' + data.key);
|
||||||
|
}
|
||||||
|
if (data.operator != user.ui.sort[0].operator) {
|
||||||
|
app.$ui.mainMenu.checkItem('sort_ordermovies_' + data.operator === '' ? 'ascending' : 'descending');
|
||||||
|
}
|
||||||
|
user.ui.sort[0] = data;
|
||||||
|
*/
|
||||||
|
app.$ui.mainMenu.checkItem('sortMenu_sortmovies_' + data.key);
|
||||||
|
app.$ui.mainMenu.checkItem('sortMenu_ordermovies_' + (data.operator === '' ? 'ascending' : 'descending'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
that.display = function() { // fixme: used?
|
||||||
|
app.$ui.rightPanel.replaceElement(1, app.$ui.contentPanel = pandora.ui.contentPanel());
|
||||||
|
};
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
21
static/js/pandora/ui/mainPanel.js
Normal file
21
static/js/pandora/ui/mainPanel.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.mainPanel = function() {
|
||||||
|
var that = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
collapsible: true,
|
||||||
|
collapsed: !app.user.ui.showSidebar,
|
||||||
|
element: app.$ui.leftPanel = pandora.ui.leftPanel(),
|
||||||
|
resizable: true,
|
||||||
|
resize: [192, 256, 320, 384],
|
||||||
|
size: app.user.ui.sidebarSize
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.rightPanel = pandora.ui.rightPanel()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'horizontal'
|
||||||
|
})
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
538
static/js/pandora/ui/menu.js
Normal file
538
static/js/pandora/ui/menu.js
Normal file
|
@ -0,0 +1,538 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.mainMenu = function() {
|
||||||
|
var isGuest = app.user.level == 'guest',
|
||||||
|
that = new Ox.MainMenu({
|
||||||
|
extras: [
|
||||||
|
$('<div>').html('beta').css({marginRight: '8px', color: 'rgb(128, 128, 128)'}),
|
||||||
|
app.$ui.loadingIcon = new Ox.LoadingIcon({
|
||||||
|
size: 'medium'
|
||||||
|
})
|
||||||
|
],
|
||||||
|
id: 'mainMenu',
|
||||||
|
menus: [
|
||||||
|
{ id: app.config.site.id + 'Menu', title: app.config.site.name, items: [
|
||||||
|
{ id: 'home', title: 'Home' },
|
||||||
|
{},
|
||||||
|
{ id: 'about', title: 'About ' + app.config.site.name },
|
||||||
|
{ id: 'news', title: app.config.site.name + ' News' },
|
||||||
|
{ id: 'tour', title: 'Take a Tour' },
|
||||||
|
{ id: 'faq', title: 'Frequently Asked Questions' },
|
||||||
|
{ id: 'terms', title: 'Terms of Service' },
|
||||||
|
{},
|
||||||
|
{ id: 'software', title: 'Software', items: [
|
||||||
|
{ id: 'about', title: 'About' },
|
||||||
|
{ id: 'download', title: 'Download' },
|
||||||
|
{ id: 'report', title: 'Report a Bug' }
|
||||||
|
] },
|
||||||
|
{},
|
||||||
|
{ id: 'contact', title: 'Contact ' + app.config.site.name }
|
||||||
|
] },
|
||||||
|
{ id: 'userMenu', title: 'User', items: [
|
||||||
|
{ id: 'username', title: 'User: ' + (isGuest ? 'not logged in' : app.user.username), disabled: true },
|
||||||
|
{},
|
||||||
|
{ id: 'preferences', title: 'Preferences...', disabled: isGuest, keyboard: 'control ,' },
|
||||||
|
{},
|
||||||
|
{ id: 'register', title: 'Register...', disabled: !isGuest },
|
||||||
|
{ id: 'loginlogout', title: isGuest ? 'Login...' : 'Logout...' }
|
||||||
|
] },
|
||||||
|
{ id: 'listMenu', title: 'List', items: [
|
||||||
|
{ id: 'history', title: 'History', items: [
|
||||||
|
{ id: 'allmovies', title: 'All ' + app.config.itemName.plural }
|
||||||
|
] },
|
||||||
|
{ id: 'lists', title: 'View List', items: [
|
||||||
|
{ id: 'favorites', title: 'Favorites' }
|
||||||
|
] },
|
||||||
|
{ id: 'features', title: 'View Feature', items: [
|
||||||
|
{ id: 'situationistfilm', title: 'Situationist Film' },
|
||||||
|
{ id: 'timelines', title: 'Timelines' }
|
||||||
|
] },
|
||||||
|
{},
|
||||||
|
{ id: 'newlist', title: 'New List...', keyboard: 'control n' },
|
||||||
|
{ id: 'newlistfromselection', title: 'New List from Selection...', disabled: true, keyboard: 'shift control n' },
|
||||||
|
{ id: 'newsmartlist', title: 'New Smart List...', keyboard: 'alt control n' },
|
||||||
|
{ id: 'newsmartlistfromresults', title: 'New Smart List from Results...', keyboard: 'shift alt control n' },
|
||||||
|
{},
|
||||||
|
{ id: 'addmovietolist', title: ['Add Selected ' + app.config.itemName.singular + ' to List...', 'Add Selected ' + app.config.itemName.plural + ' to List...'], disabled: true },
|
||||||
|
{},
|
||||||
|
{ id: 'setposterframe', title: 'Set Poster Frame', disabled: true }
|
||||||
|
]},
|
||||||
|
{ id: 'editMenu', title: 'Edit', items: [
|
||||||
|
{ id: 'undo', title: 'Undo', disabled: true, keyboard: 'control z' },
|
||||||
|
{ id: 'redo', title: 'Redo', disabled: true, keyboard: 'shift control z' },
|
||||||
|
{},
|
||||||
|
{ id: 'cut', title: 'Cut', disabled: true, keyboard: 'control x' },
|
||||||
|
{ id: 'copy', title: 'Copy', disabled: true, keyboard: 'control c' },
|
||||||
|
{ id: 'paste', title: 'Paste', disabled: true, keyboard: 'control v' },
|
||||||
|
{ id: 'delete', title: 'Delete', disabled: true, keyboard: 'delete' },
|
||||||
|
{},
|
||||||
|
{ id: 'selectall', title: 'Select All', disabled: true, keyboard: 'control a' },
|
||||||
|
{ id: 'selectnone', title: 'Select None', disabled: true, keyboard: 'shift control a' },
|
||||||
|
{ id: 'invertselection', title: 'Invert Selection', disabled: true, keyboard: 'alt control a' }
|
||||||
|
] },
|
||||||
|
{ id: 'viewMenu', title: 'View', items: [
|
||||||
|
{ id: 'movies', title: 'View ' + app.config.itemName.plural, items: [
|
||||||
|
{ group: 'viewmovies', min: 0, max: 1, items: $.map(app.config.listViews, function(view, i) {
|
||||||
|
return $.extend({
|
||||||
|
checked: app.user.ui.lists[app.user.ui.list].listView == view.id,
|
||||||
|
}, view);
|
||||||
|
}) },
|
||||||
|
]},
|
||||||
|
{ id: 'icons', title: 'Icons', items: [
|
||||||
|
{ id: 'poster', title: 'Poster' },
|
||||||
|
{ id: 'still', title: 'Still' },
|
||||||
|
{ id: 'timeline', title: 'Timeline' }
|
||||||
|
] },
|
||||||
|
{ id: 'info', title: 'Info', items: [
|
||||||
|
{ id: 'poster', title: 'Poster' },
|
||||||
|
{ id: 'video', title: 'Video' }
|
||||||
|
] },
|
||||||
|
{},
|
||||||
|
{ id: 'openmovie', title: ['Open ' + app.config.itemName.singular, 'Open ' + app.config.itemName.plural], disabled: true, items: [
|
||||||
|
{ group: 'movieview', min: 0, max: 1, items: $.map(app.config.itemViews, function(view, i) {
|
||||||
|
return $.extend({
|
||||||
|
checked: app.user.ui.itemView == view.id,
|
||||||
|
}, view);
|
||||||
|
}) },
|
||||||
|
]},
|
||||||
|
{},
|
||||||
|
{ id: 'lists', title: 'Hide Lists', keyboard: 'shift l' },
|
||||||
|
{ id: 'info', title: 'Hide Info', keyboard: 'shift i' },
|
||||||
|
{ id: 'groups', title: 'Hide Groups', keyboard: 'shift g' },
|
||||||
|
{ id: 'movies', title: 'Hide ' + app.config.itemName.plural, disabled: true, keyboard: 'shift m' }
|
||||||
|
]},
|
||||||
|
{ id: 'sortMenu', title: 'Sort', items: [
|
||||||
|
{ id: 'sortmovies', title: 'Sort ' + app.config.itemName.plural + ' by', items: [
|
||||||
|
{ group: 'sortmovies', min: 1, max: 1, items: $.map(app.ui.sortKeys, function(key, i) {
|
||||||
|
return $.extend({
|
||||||
|
checked: app.user.ui.lists[app.user.ui.list].sort[0].key == key.id,
|
||||||
|
}, key);
|
||||||
|
}) }
|
||||||
|
] },
|
||||||
|
{ id: 'ordermovies', title: 'Order ' + app.config.itemName.plural, items: [
|
||||||
|
{ group: 'ordermovies', min: 1, max: 1, items: [
|
||||||
|
{ id: 'ascending', title: 'Ascending', checked: app.user.ui.lists[app.user.ui.list].sort[0].operator === '' },
|
||||||
|
{ id: 'descending', title: 'Descending', checked: app.user.ui.lists[app.user.ui.list].sort[0].operator == '-' }
|
||||||
|
]}
|
||||||
|
] },
|
||||||
|
{ id: 'advancedsort', title: 'Advanced Sort...', keyboard: 'shift control s' },
|
||||||
|
{},
|
||||||
|
{ id: 'groupsstuff', title: 'Groups Stuff' }
|
||||||
|
] },
|
||||||
|
{ id: 'findMenu', title: 'Find', items: [
|
||||||
|
{ id: 'find', title: 'Find', items: [
|
||||||
|
{ group: 'find', min: 1, max: 1, items: $.map(app.ui.findKeys, function(key, i) {
|
||||||
|
return $.extend({
|
||||||
|
checked: app.user.ui.findQuery.conditions.length &&
|
||||||
|
(app.user.ui.findQuery.conditions[0].key == key.id ||
|
||||||
|
(app.user.ui.findQuery.conditions[0].key === '' && key.id == 'all')),
|
||||||
|
}, key)
|
||||||
|
}) }
|
||||||
|
] },
|
||||||
|
{ id: 'advancedfind', title: 'Advanced Find...', keyboard: 'shift control f' }
|
||||||
|
] },
|
||||||
|
{ id: 'dataMenu', title: 'Data', items: [
|
||||||
|
{ id: 'titles', title: 'Manage Titles...' },
|
||||||
|
{ id: 'names', title: 'Manage Names...' },
|
||||||
|
{},
|
||||||
|
{ id: 'posters', title: 'Manage Stills...' },
|
||||||
|
{ id: 'posters', title: 'Manage Posters...' },
|
||||||
|
{},
|
||||||
|
{ id: 'places', title: 'Manage Places...' },
|
||||||
|
{ id: 'events', title: 'Manage Events...' },
|
||||||
|
{},
|
||||||
|
{ id: 'users', title: 'Manage Users...' },
|
||||||
|
{ id: 'lists', title: 'Manage Lists...' },
|
||||||
|
] },
|
||||||
|
{ id: 'codeMenu', title: 'Code', items: [
|
||||||
|
{ id: 'download', title: 'Download' },
|
||||||
|
{ id: 'contribute', title: 'Contribute' },
|
||||||
|
{ id: 'report', title: 'Report a Bug' },
|
||||||
|
] },
|
||||||
|
{ id: 'helpMenu', title: 'Help', items: [
|
||||||
|
{ id: 'help', title: app.config.site.name + ' Help', keyboard: 'shift ?' }
|
||||||
|
] },
|
||||||
|
{ id: 'debugMenu', title: 'Debug', items: [
|
||||||
|
{ id: 'query', title: 'Show pandora.Query' },
|
||||||
|
{ id: 'resetui', title: 'Reset UI Settings'}
|
||||||
|
] },
|
||||||
|
{ id: 'testMenu', title: 'Test', items: [
|
||||||
|
{ group: 'foogroup', items: [
|
||||||
|
{ id: 'item1', title: 'Item 1' },
|
||||||
|
{ id: 'item2', title: 'Item 2' }
|
||||||
|
] }
|
||||||
|
] }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
if (data.id == 'find') {
|
||||||
|
var id = data.checked[0].id;
|
||||||
|
app.$ui.findSelect.selectItem(id);
|
||||||
|
} else if (data.id == 'movieview') {
|
||||||
|
var view = data.checked[0].id;
|
||||||
|
var id = document.location.pathname.split('/')[1];
|
||||||
|
if (view == 'info')
|
||||||
|
url(id + '/info');
|
||||||
|
else
|
||||||
|
url(id);
|
||||||
|
} else if (data.id == 'ordermovies') {
|
||||||
|
var id = data.checked[0].id;
|
||||||
|
app.$ui.list.sortList(app.user.ui.lists[app.user.ui.list].sort[0].key, id == 'ascending' ? '' : '-');
|
||||||
|
} else if (data.id == 'sortmovies') {
|
||||||
|
var id = data.checked[0].id,
|
||||||
|
operator = pandora.getSortOperator(id);
|
||||||
|
app.$ui.mainMenu.checkItem('sortMenu_ordermovies_' + (operator === '' ? 'ascending' : 'descending'));
|
||||||
|
app.$ui.sortSelect.selectItem(id);
|
||||||
|
app.$ui.list.sortList(id, operator);
|
||||||
|
pandora.URL.set(pandora.Query.toString());
|
||||||
|
} else if (data.id == 'viewmovies') {
|
||||||
|
var view = data.checked[0].id;
|
||||||
|
url('#view=' + view);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
click: function(event, data) {
|
||||||
|
if (data.id == 'about') {
|
||||||
|
var $dialog = new Ox.Dialog({
|
||||||
|
buttons: [
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'close',
|
||||||
|
title: 'Close'
|
||||||
|
}).bindEvent({
|
||||||
|
click: function() {
|
||||||
|
$dialog.close();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
id: 'about',
|
||||||
|
title: 'About'
|
||||||
|
}).open();
|
||||||
|
} else if (data.id == 'home') {
|
||||||
|
var $dialog = new Ox.Dialog({
|
||||||
|
buttons: [
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'close',
|
||||||
|
title: 'Close'
|
||||||
|
}).bindEvent({
|
||||||
|
click: function() {
|
||||||
|
$dialog.close();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
height: 498,
|
||||||
|
id: 'home',
|
||||||
|
keys: {enter: 'close', escape: 'close'},
|
||||||
|
title: app.config.site.name,
|
||||||
|
width: 800
|
||||||
|
}).open();
|
||||||
|
} else if (data.id == 'register') {
|
||||||
|
app.$ui.accountDialog = pandora.ui.accountDialog('register').open();
|
||||||
|
} else if (data.id == 'loginlogout') {
|
||||||
|
app.$ui.accountDialog = (app.user.level == 'guest' ?
|
||||||
|
pandora.ui.accountDialog('login') : pandora.ui.accountLogoutDialog()).open();
|
||||||
|
} else if (data.id == 'places') {
|
||||||
|
app.$ui.placesDialog = pandora.ui.placesDialog().open();
|
||||||
|
/*
|
||||||
|
var $manage = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
collapsible: true,
|
||||||
|
element: new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: new Ox.Toolbar({
|
||||||
|
orientation: 'horizontal',
|
||||||
|
size: 44
|
||||||
|
}).append(
|
||||||
|
app.$ui.findPlacesElement = new Ox.FormElementGroup({
|
||||||
|
elements: [
|
||||||
|
app.$ui.findPlacesSelect = new Ox.Select({
|
||||||
|
id: 'findPlacesSelect',
|
||||||
|
items: [
|
||||||
|
{ id: 'name', title: 'Find: Name' },
|
||||||
|
{ id: 'region', title: 'Find: Region' },
|
||||||
|
{ id: 'user', title: 'Find: User' }
|
||||||
|
],
|
||||||
|
overlap: 'right',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
app.$ui.findPlacesSelect.loseFocus();
|
||||||
|
app.$ui.findPlacesInput.options({
|
||||||
|
placeholder: data.selected[0].title
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
app.$ui.findPlacesInput = new Ox.Input({
|
||||||
|
clear: true,
|
||||||
|
id: 'findPlacesInput',
|
||||||
|
placeholder: 'Find: Name',
|
||||||
|
width: 234
|
||||||
|
})
|
||||||
|
],
|
||||||
|
id: 'findPlacesElement'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px'
|
||||||
|
})
|
||||||
|
).append(
|
||||||
|
app.$ui.sortPlacesSelect = new Ox.Select({
|
||||||
|
id: 'sortPlacesSelect',
|
||||||
|
items: [
|
||||||
|
{ id: 'name', title: 'Sort by Name', checked: true },
|
||||||
|
{ id: 'region', title: 'Sort by Region' },
|
||||||
|
{ id: 'size', title: 'Sort by Size' },
|
||||||
|
{ id: 'latitude', title: 'Sort by Latitude' },
|
||||||
|
{ id: 'longitude', title: 'Sort by Longitude' },
|
||||||
|
{ id: 'clips', title: 'Sort by Number of Clips' },
|
||||||
|
{ id: 'user', title: 'Sort by User' },
|
||||||
|
{ id: 'datecreated', title: 'Sort by Date Added' },
|
||||||
|
{ id: 'datemodified', title: 'Sort by Date Modified' }
|
||||||
|
],
|
||||||
|
width: 246
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '0 4px 4px 4px'
|
||||||
|
})
|
||||||
|
),
|
||||||
|
size: 44
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: new Ox.Element('div')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: new Ox.Toolbar({
|
||||||
|
orientation: 'horizontal',
|
||||||
|
size: 16
|
||||||
|
}),
|
||||||
|
size: 16
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'vertical'
|
||||||
|
}),
|
||||||
|
size: 256
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: new Ox.Toolbar({
|
||||||
|
orientation: 'horizontal',
|
||||||
|
size: 24
|
||||||
|
}).append(
|
||||||
|
app.$ui.labelsButton = new Ox.Button({
|
||||||
|
id: 'labelsButton',
|
||||||
|
title: [
|
||||||
|
{id: 'show', title: 'Show Labels'},
|
||||||
|
{id: 'hide', title: 'Hide Labels'}
|
||||||
|
],
|
||||||
|
width: 96
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px'
|
||||||
|
})
|
||||||
|
).append(
|
||||||
|
app.$ui.findMapInput = new Ox.Input({
|
||||||
|
clear: true,
|
||||||
|
id: 'findMapInput',
|
||||||
|
placeholder: 'Find on Map',
|
||||||
|
width: 192
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'right',
|
||||||
|
margin: '4px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
submit: function(event, data) {
|
||||||
|
app.$ui.map.find(data.value, function(location) {
|
||||||
|
|
||||||
|
app.$ui.placeNameInput.options({
|
||||||
|
disabled: false,
|
||||||
|
value: location.name
|
||||||
|
});
|
||||||
|
app.$ui.placeAliasesInput.options({
|
||||||
|
disabled: false
|
||||||
|
});
|
||||||
|
app.$ui.placeGeonameLabel.options({
|
||||||
|
disabled: false,
|
||||||
|
title: location.names.join(', ')
|
||||||
|
});
|
||||||
|
app.$ui.removePlaceButton.options({
|
||||||
|
disabled: false
|
||||||
|
});
|
||||||
|
app.$ui.addPlaceButton.options({
|
||||||
|
disabled: false
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
),
|
||||||
|
size: 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.map = new Ox.Map({
|
||||||
|
places: ['Boston', 'Brussels', 'Barcelona', 'Berlin', 'Beirut', 'Bombay', 'Bangalore', 'Beijing']
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
select: function(event, location) {
|
||||||
|
app.$ui.placeNameInput.options({
|
||||||
|
disabled: false,
|
||||||
|
value: location.name
|
||||||
|
});
|
||||||
|
app.$ui.placeAliasesInput.options({
|
||||||
|
disabled: false
|
||||||
|
});
|
||||||
|
app.$ui.placeGeonameLabel.options({
|
||||||
|
disabled: false,
|
||||||
|
title: location.names.join(', ')
|
||||||
|
});
|
||||||
|
app.$ui.removePlaceButton.options({
|
||||||
|
disabled: false
|
||||||
|
});
|
||||||
|
app.$ui.addPlaceButton.options({
|
||||||
|
disabled: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.bottomBar = new Ox.Toolbar({
|
||||||
|
orientation: 'horizontal',
|
||||||
|
size: 24
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
app.$ui.placeNameInput = new Ox.Input({
|
||||||
|
disabled: true,
|
||||||
|
id: 'placeName',
|
||||||
|
placeholder: 'Name',
|
||||||
|
width: 128
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px 0 0 4px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
app.$ui.placeAliasesInput = new Ox.Input({
|
||||||
|
disabled: true,
|
||||||
|
id: 'aliases',
|
||||||
|
placeholder: 'Aliases',
|
||||||
|
width: 128
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px 0 0 4px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
app.$ui.placeGeonameLabel = new Ox.Label({
|
||||||
|
disabled: true,
|
||||||
|
id: 'placeGeoname',
|
||||||
|
title: 'Geoname',
|
||||||
|
width: parseInt(app.$ui.document.width() * 0.8) - 256 - 256 - 32 - 24
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px 0 0 4px'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
app.$ui.addPlaceButton = new Ox.Button({
|
||||||
|
disabled: true,
|
||||||
|
id: 'addPlaceButton',
|
||||||
|
title: 'add',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'right',
|
||||||
|
margin: '4px 4px 0 0'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
app.$ui.removePlaceButton = new Ox.Button({
|
||||||
|
disabled: true,
|
||||||
|
id: 'removePlaceButton',
|
||||||
|
title: 'remove',
|
||||||
|
type: 'image'
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'right',
|
||||||
|
margin: '4px 4px 0 0'
|
||||||
|
})
|
||||||
|
),
|
||||||
|
size: 24
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'vertical'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
],
|
||||||
|
orientation: 'horizontal'
|
||||||
|
}).css({
|
||||||
|
top: '24px',
|
||||||
|
bottom: '24px',
|
||||||
|
}),
|
||||||
|
$dialog = new Ox.Dialog({
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
click: function() {
|
||||||
|
$dialog.close();
|
||||||
|
},
|
||||||
|
id: 'close',
|
||||||
|
title: 'Close',
|
||||||
|
value: 'Close'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
height: parseInt(app.$ui.document.height() * 0.8),
|
||||||
|
id: 'places',
|
||||||
|
minHeight: 400,
|
||||||
|
minWidth: 600,
|
||||||
|
padding: 0,
|
||||||
|
title: 'Manage Places',
|
||||||
|
width: parseInt(app.$ui.document.width() * 0.8)
|
||||||
|
}).css({
|
||||||
|
overflow: 'hidden'
|
||||||
|
}).append($manage).open();
|
||||||
|
*/
|
||||||
|
} else if (data.id == 'query') {
|
||||||
|
var $dialog = new Ox.Dialog({
|
||||||
|
buttons: [
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'close',
|
||||||
|
title: 'Close'
|
||||||
|
}).bindEvent({
|
||||||
|
click: function() {
|
||||||
|
$dialog.close();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
content: new Ox.Element()
|
||||||
|
.html([
|
||||||
|
'Query: ' + JSON.stringify(pandora.Query.toObject()),
|
||||||
|
'findQuery: ' + JSON.stringify(app.user.ui.findQuery),
|
||||||
|
'listQuery: ' + JSON.stringify(app.user.ui.listQuery)
|
||||||
|
].join('<br/><br/>')),
|
||||||
|
height: 200,
|
||||||
|
keys: {enter: 'close', escape: 'close'},
|
||||||
|
width: 400
|
||||||
|
}).open();
|
||||||
|
} else if (data.id == 'resetui') {
|
||||||
|
pandora.api.resetUI({}, function() {
|
||||||
|
app.$ui.appPanel.reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
67
static/js/pandora/ui/placesDialog.js
Normal file
67
static/js/pandora/ui/placesDialog.js
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.placesDialog = function() {
|
||||||
|
var height = Math.round(document.height * 0.8),
|
||||||
|
width = Math.round(document.width * 0.8),
|
||||||
|
that = new Ox.Dialog({
|
||||||
|
buttons: [
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'done',
|
||||||
|
title: 'Done'
|
||||||
|
}).bindEvent({
|
||||||
|
click: function() {
|
||||||
|
that.close();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
content: app.$ui.placesElement = new Ox.ListMap({
|
||||||
|
height: height - 48,
|
||||||
|
places: function(data, callback) {
|
||||||
|
return pandora.api.findPlaces($.extend(data, {
|
||||||
|
query: {conditions: [], operator: ''}
|
||||||
|
}), callback);
|
||||||
|
},
|
||||||
|
width: width
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
addplace: function(event, data) {
|
||||||
|
Ox.print('ADDPLACE', data)
|
||||||
|
pandora.api.addPlace(data.place, function(result) {
|
||||||
|
var id = result.data.id;
|
||||||
|
Ox.print("ID", result.data.id, result)
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
Ox.print('AAAAA')
|
||||||
|
app.$ui.placesElement
|
||||||
|
.reloadList()
|
||||||
|
.bindEventOnce({
|
||||||
|
loadlist: function() {
|
||||||
|
app.$ui.placesElement
|
||||||
|
.focusList()
|
||||||
|
.options({selected: [id]});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
removeplace: function(event, data) {
|
||||||
|
pandora.api.removePlace(data.id, function(result) {
|
||||||
|
// fixme: duplicated
|
||||||
|
Ox.Request.clearCache(); // fixme: remove
|
||||||
|
app.$ui.placesElement
|
||||||
|
.reloadList()
|
||||||
|
.bindEventOnce({
|
||||||
|
loadlist: function(event, data) {
|
||||||
|
app.$ui.placesElement
|
||||||
|
.focusList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
height: height,
|
||||||
|
keys: {enter: 'done', escape: 'done'},
|
||||||
|
padding: 0,
|
||||||
|
title: 'Manage Places',
|
||||||
|
width: width
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
0
static/js/pandora/ui/player.js
Normal file
0
static/js/pandora/ui/player.js
Normal file
25
static/js/pandora/ui/publicLists.js
Normal file
25
static/js/pandora/ui/publicLists.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.publicListsDialog = function() { // fixme: unused
|
||||||
|
var that = new Ox.Dialog({
|
||||||
|
buttons: [
|
||||||
|
new Ox.Button({
|
||||||
|
id: 'done',
|
||||||
|
title: 'Done'
|
||||||
|
}).bindEvent({
|
||||||
|
click: function() {
|
||||||
|
that.close();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
content: pandora.ui.publicListsList(),
|
||||||
|
height: 320,
|
||||||
|
keys: {enter: 'close', escape: 'close'},
|
||||||
|
padding: 0,
|
||||||
|
title: 'Public Lists',
|
||||||
|
width: 420
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
position: 'absolute'
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
56
static/js/pandora/ui/rightPanel.js
Normal file
56
static/js/pandora/ui/rightPanel.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.rightPanel = function() {
|
||||||
|
var that;
|
||||||
|
if (app.user.ui.section == 'site') {
|
||||||
|
that = new Ox.Element()
|
||||||
|
.html(app.user.ui.sitePage)
|
||||||
|
.bindEvent({
|
||||||
|
resize: function(event, data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pandora.api.getPage(app.user.ui.sitePage, function(result) {
|
||||||
|
that.html(result.data.body).css({'overflow-y':'auto'});
|
||||||
|
});
|
||||||
|
} else if (app.user.ui.section == 'items') {
|
||||||
|
that = new Ox.SplitPanel({
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
element: app.$ui.toolbar = pandora.ui.toolbar(),
|
||||||
|
size: 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.contentPanel = pandora.ui.contentPanel()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: app.$ui.statusbar = pandora.ui.statusbar(),
|
||||||
|
size: 16
|
||||||
|
}
|
||||||
|
],
|
||||||
|
id: 'rightPanel',
|
||||||
|
orientation: 'vertical'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
resize: function(event, data) {
|
||||||
|
//Ox.print('???? resize rightPanel', event, data)
|
||||||
|
if (!app.user.ui.item) {
|
||||||
|
resizeGroups(data);
|
||||||
|
app.$ui.list.size();
|
||||||
|
if (app.user.ui.lists[app.user.ui.list].listView == 'map') {
|
||||||
|
app.$ui.map.resize();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
app.$ui.browser.scrollToSelection();
|
||||||
|
app.user.ui.itemView == 'player' && app.$ui.player.options({
|
||||||
|
width: data
|
||||||
|
});
|
||||||
|
app.user.ui.itemView == 'timeline' && app.$ui.editor.options({
|
||||||
|
width: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
28
static/js/pandora/ui/sectionButtons.js
Normal file
28
static/js/pandora/ui/sectionButtons.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.sectionButtons = function() {
|
||||||
|
var that = new Ox.ButtonGroup({
|
||||||
|
buttons: [
|
||||||
|
{id: 'site', selected: app.user.ui.section == 'site', title: app.config.site.name},
|
||||||
|
{id: 'items', selected: app.user.ui.section == 'items', title: app.config.itemName.plural},
|
||||||
|
{id: 'texts', selected: app.user.ui.section == 'texts', title: 'Texts'},
|
||||||
|
{id: 'admin', selected: app.user.ui.section == 'admin', title: 'Admin'}
|
||||||
|
],
|
||||||
|
id: 'sectionButtons',
|
||||||
|
selectable: true
|
||||||
|
}).css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
var section = data.selected[0];
|
||||||
|
if (section == 'site') {
|
||||||
|
pandora.URL.set(app.user.ui.sitePage);
|
||||||
|
} else if (section == 'items') {
|
||||||
|
pandora.URL.set(pandora.Query.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
21
static/js/pandora/ui/sectionSelect.js
Normal file
21
static/js/pandora/ui/sectionSelect.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.sectionSelect = function() {
|
||||||
|
// fixme: duplicated
|
||||||
|
var that = new Ox.Select({
|
||||||
|
id: 'sectionSelect',
|
||||||
|
items: [
|
||||||
|
{checked: app.user.ui.section == 'site', id: 'site', title: app.config.site.name},
|
||||||
|
{checked: app.user.ui.section == 'items', id: 'items', title: app.config.itemName.plural},
|
||||||
|
{checked: app.user.ui.section == 'texts', id: 'texts', title: 'Texts'},
|
||||||
|
{checked: app.user.ui.section == 'admin', id: 'admin', title: 'Admin'}
|
||||||
|
]
|
||||||
|
}).css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
16
static/js/pandora/ui/sectionbar.js
Normal file
16
static/js/pandora/ui/sectionbar.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.sectionbar = function(mode) {
|
||||||
|
var that = new Ox.Bar({
|
||||||
|
size: 24
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
mode == 'buttons' ?
|
||||||
|
app.$ui.sectionButtons = pandora.ui.sectionButtons() :
|
||||||
|
app.$ui.sectionSelect = pandora.ui.sectionSelect()
|
||||||
|
);
|
||||||
|
that.toggle = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
36
static/js/pandora/ui/sortSelect.js
Normal file
36
static/js/pandora/ui/sortSelect.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.sortSelect = function() {
|
||||||
|
var that = new Ox.Select({
|
||||||
|
id: 'sortSelect',
|
||||||
|
items: $.map(app.ui.sortKeys, function(key) {
|
||||||
|
//Ox.print('????', app.user.ui.lists[app.user.ui.list].sort.key, key.id)
|
||||||
|
return $.extend($.extend({}, key), {
|
||||||
|
checked: app.user.ui.lists[app.user.ui.list].sort[0].key == key.id,
|
||||||
|
title: 'Sort by ' + key.title
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
width: 144
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px 0 0 4px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: function(event, data) {
|
||||||
|
var id = data.selected[0].id,
|
||||||
|
operator = pandora.getSortOperator(id);
|
||||||
|
/*
|
||||||
|
app.user.ui.lists[app.user.ui.list].sort[0] = {
|
||||||
|
key: id,
|
||||||
|
operator: operator
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
app.$ui.mainMenu.checkItem('sortMenu_sortmovies_' + id);
|
||||||
|
app.$ui.mainMenu.checkItem('sortMenu_ordermovies_' + (operator === '' ? 'ascending' : 'descending'));
|
||||||
|
app.$ui.list.sortList(id, operator);
|
||||||
|
pandora.URL.set(pandora.Query.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
13
static/js/pandora/ui/status.js
Normal file
13
static/js/pandora/ui/status.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.status = function(key, data) {
|
||||||
|
var that = Ox.toTitleCase(key) + ': ' + [
|
||||||
|
Ox.formatNumber(data.items) + ' movie' + (data.items != 1 ? 's' : ''),
|
||||||
|
Ox.formatDuration(data.runtime, 'medium'),
|
||||||
|
data.files + ' file' + (data.files != 1 ? 's' : ''),
|
||||||
|
Ox.formatDuration(data.duration, 'short'),
|
||||||
|
Ox.formatValue(data.size, 'B'),
|
||||||
|
Ox.formatValue(data.pixels, 'px')
|
||||||
|
].join(', ');
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
27
static/js/pandora/ui/statusbar.js
Normal file
27
static/js/pandora/ui/statusbar.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.statusbar = function() {
|
||||||
|
var that = new Ox.Bar({
|
||||||
|
size: 16
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
textAlign: 'center'
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
new Ox.Element()
|
||||||
|
.css({
|
||||||
|
marginTop: '2px',
|
||||||
|
fontSize: '9px'
|
||||||
|
})
|
||||||
|
.append(
|
||||||
|
app.$ui.total = new Ox.Element('span')
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
new Ox.Element('span').html(' — ')
|
||||||
|
)
|
||||||
|
.append(
|
||||||
|
app.$ui.selected = new Ox.Element('span')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
25
static/js/pandora/ui/toolbar.js
Normal file
25
static/js/pandora/ui/toolbar.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.toolbar = function() {
|
||||||
|
var that = new Ox.Bar({
|
||||||
|
size: 24
|
||||||
|
}).css({
|
||||||
|
zIndex: 2 // fixme: remove later
|
||||||
|
});
|
||||||
|
app.user.ui.item && that.append(
|
||||||
|
app.$ui.backButton = pandora.ui.backButton()
|
||||||
|
);
|
||||||
|
that.append(
|
||||||
|
app.$ui.viewSelect = pandora.ui.viewSelect()
|
||||||
|
);
|
||||||
|
!app.user.ui.item && that.append(
|
||||||
|
app.$ui.sortSelect = pandora.ui.sortSelect()
|
||||||
|
);
|
||||||
|
that.append(
|
||||||
|
app.$ui.findElement = pandora.ui.findElement()
|
||||||
|
);
|
||||||
|
that.display = function() {
|
||||||
|
app.$ui.rightPanel.replaceElement(0, app.$ui.toolbar = pandora.ui.toolbar()); // fixme: remove later
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
37
static/js/pandora/ui/viewSelect.js
Normal file
37
static/js/pandora/ui/viewSelect.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
pandora.ui.viewSelect = function() {
|
||||||
|
var that = new Ox.Select({
|
||||||
|
id: 'viewSelect',
|
||||||
|
items: !app.user.ui.item ? $.map(app.config.listViews, function(view) {
|
||||||
|
return $.extend($.extend({}, view), {
|
||||||
|
checked: app.user.ui.lists[app.user.ui.list].listView == view.id,
|
||||||
|
title: 'View ' + view.title
|
||||||
|
});
|
||||||
|
}) : $.map(app.config.itemViews, function(view) {
|
||||||
|
return $.extend($.extend({}, view), {
|
||||||
|
checked: app.user.ui.itemView == view.id,
|
||||||
|
title: 'View: ' + view.title
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
width: !app.user.ui.item ? 144 : 128
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
float: 'left',
|
||||||
|
margin: '4px 0 0 4px'
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
change: !app.user.ui.item ? function(event, data) {
|
||||||
|
var id = data.selected[0].id;
|
||||||
|
app.$ui.mainMenu.checkItem('viewMenu_movies_' + id);
|
||||||
|
pandora.UI.set(['lists', app.user.ui.list, 'listView'].join('|'), id);
|
||||||
|
pandora.URL.set(pandora.Query.toString());
|
||||||
|
} : function(event, data) {
|
||||||
|
var id = data.selected[0].id;
|
||||||
|
//pandora.UI.set({itemView: id});
|
||||||
|
pandora.URL.set(app.user.ui.item + '/' + id);
|
||||||
|
// app.$ui.contentPanel.replaceElement(1, app.$ui.item = pandora.ui.item());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
|
41
static/json/pandora.json
Normal file
41
static/json/pandora.json
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
[
|
||||||
|
"js/pandora/pandora.js",
|
||||||
|
"js/pandora/URL.js",
|
||||||
|
"js/pandora/Query.js",
|
||||||
|
"js/pandora/autovalidate.js",
|
||||||
|
"js/pandora/UI.js",
|
||||||
|
"js/pandora/ui/info.js",
|
||||||
|
"js/pandora/ui/rightPanel.js",
|
||||||
|
"js/pandora/ui/folderBrowserList.js",
|
||||||
|
"js/pandora/ui/group.js",
|
||||||
|
"js/pandora/ui/toolbar.js",
|
||||||
|
"js/pandora/ui/statusbar.js",
|
||||||
|
"js/pandora/ui/player.js",
|
||||||
|
"js/pandora/ui/sectionButtons.js",
|
||||||
|
"js/pandora/ui/item.js",
|
||||||
|
"js/pandora/ui/folderBrowser.js",
|
||||||
|
"js/pandora/ui/publicLists.js",
|
||||||
|
"js/pandora/ui/filter.js",
|
||||||
|
"js/pandora/ui/status.js",
|
||||||
|
"js/pandora/ui/sectionbar.js",
|
||||||
|
"js/pandora/ui/folders.js",
|
||||||
|
"js/pandora/ui/mainPanel.js",
|
||||||
|
"js/pandora/ui/sortSelect.js",
|
||||||
|
"js/pandora/ui/menu.js",
|
||||||
|
"js/pandora/ui/viewSelect.js",
|
||||||
|
"js/pandora/ui/browser.js",
|
||||||
|
"js/pandora/ui/list.js",
|
||||||
|
"js/pandora/ui/foldersList.js",
|
||||||
|
"js/pandora/ui/findElement.js",
|
||||||
|
"js/pandora/ui/filterDialog.js",
|
||||||
|
"js/pandora/ui/account.js",
|
||||||
|
"js/pandora/ui/folderBrowserBar.js",
|
||||||
|
"js/pandora/ui/sectionSelect.js",
|
||||||
|
"js/pandora/ui/placesDialog.js",
|
||||||
|
"js/pandora/ui/contentPanel.js",
|
||||||
|
"js/pandora/ui/backButton.js",
|
||||||
|
"js/pandora/ui/leftPanel.js",
|
||||||
|
"js/pandora/ui/appPanel.js",
|
||||||
|
"js/pandora/ui/flipbook.js",
|
||||||
|
"js/pandora/ui/editor.js"
|
||||||
|
]
|
Loading…
Reference in a new issue