')
.css({
width: '100px',
height: '100px',
background: 'red'
});
}
['list', 'icons'].indexOf(view) > -1 && that.bind({
dragstart: function(e) {
app.$ui.sectionList.forEach(function($list, i) {
$list.addClass('OxDrop');
});
},
dragend: function(e) {
app.$ui.sectionList.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(ui.status('total', data));
data = [];
$.each(app.config.totals, function(i, v) {
data[v.id] = 0;
});
app.$ui.selected.html(ui.status('selected', data));
},
open: function(event, data) {
var id = data.ids[0],
title = that.value(id, 'title');
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 = $('
')
.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) {
$still = $('
')
.attr({
src: 'http://0xdb.org/' + data.ids[0] + '/still.jpg'
})
.one('load', function() {
if (data.ids[0] != app.ui.selectedMovies[0]) {
//Ox.print('cancel after load...')
return;
}
var image = $still[0],
imageWidth = image.width,
imageHeight = image.height,
width = app.$ui.info.width(),
height = imageHeight * width / imageWidth;
app.ui.infoRatio = width / height;
!app.user.ui.showInfo && app.$ui.leftPanel.css({bottom: -height - 16});
app.$ui.leftPanel.size('infoPanel', height + 16);
$still.css({
position: 'absolute',
left: 0,
top: 0,
//width: width + 'px',
//height: height + 'px',
width: '100%',
opacity: 0
})
.appendTo(app.$ui.info.$element)
.animate({
opacity: 1
});
app.$ui.infoStill.animate({
opacity: 0
}, 250);
app.$ui.info.animate({
height: (height + 16) + 'px'
}, 250, function() {
app.$ui.infoStill.remove();
app.$ui.infoStill = $still;
resizeSections();
});
});
/*
$timeline = $('
')
.attr({
src: 'http://0xdb.org/' + data.ids[0] + '/timeline/timeline.png'
})
.one('load', function() {
$timeline.css({
position: 'absolute',
left: 0,
bottom: '16px',
opacity: 0
})
.appendTo($ui.info.$element)
.animate({
opacity: 1
});
$ui.infoTimeline.animate({
opacity: 0
}, 250, function() {
$ui.infoTimeline.remove();
$ui.infoTimeline = $timeline;
});
});
*/
}
pandora.api.find({
query: {
conditions: $.map(data.ids, function(id, i) {
return {
key: 'id',
value: id,
operator: '='
}
}),
operator: '|'
}
}, function(result) {
app.$ui.selected.html(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.replace(1, app.$ui.contentPanel = ui.contentPanel());
};
return that;
},
listsBar: function(id) {
var that = new Ox.Bar({
size: 24
});
app.$ui.findListInput = new Ox.Input({
placeholder: 'Find User',
width: 184 - app.ui.scrollbarSize
})
.css({
margin: '4px',
align: 'right'
})
.appendTo(that);
return that;
},
listsBrowser: function(id) {
var that = new Ox.SplitPanel({
elements: [
{
element: ui.listsBar(),
size: 24
},
{
element: app.$ui.sectionList[id == 'public' ? 1 : 2] = ui.listsList(id)
}
],
orientation: 'vertical'
});
return that;
},
listsList: function(id) {
var columnWidth = (app.user.ui.sidebarSize - app.ui.scrollbarSize - 88) / 2,
i = ['my', 'public', 'featured'].indexOf(id), // fixme: find a better way
that = new Ox.TextList({
columns: [
{
format: function() {
return $('
').attr({
src: 'static/oxjs/build/png/ox.ui/icon16.png'
});
},
id: 'id',
operator: '+',
title: $('
').attr({
src: 'static/oxjs/build/png/ox.ui/icon16.png'
}),
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 $('
')
.attr({
src: 'static/oxjs/build/png/ox.ui.' + Ox.theme() +
'/symbolFind.png'
})
.css({
opacity: value == 'static' ? 0.1 : 1
});
},
id: 'type',
operator: '+',
title: $('
').attr({
src: 'static/oxjs/build/png/ox.ui.' +
Ox.theme() + '/symbolFind.png'
}),
visible: true,
width: 16
},
{
clickable: true,
format: function(value) {
return $('
')
.attr({
src: 'static/oxjs/build/png/ox.ui.' + Ox.theme() +
'/symbol' + (id == 'public' ? 'Check' : 'Star') + '.png'
})
.css({
opacity: id == 'public' ? (value ? 1 : 0.1) :
(value == 'featured' ? 1 : 0.1)
});
},
id: id == 'public' ? 'subscribed' : 'status',
operator: '+',
title: $('
').attr({
src: 'static/oxjs/build/png/ox.ui.' + Ox.theme() +
'/symbol' + (id == 'public' ? 'Check' : 'Star') + '.png'
}),
visible: true,
width: 16
},
],
columnsVisible: true,
pageLength: 1000,
request: function(data, callback) {
var query = id == 'public' ? {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);
},
// 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.emptyCache(); // fixme: remove
app.$ui.sectionList[
result.data.user == app.user.username ? 0 : 1
].reloadList();
}
that.value(data.id, 'status', result.data.status);
});
}
},
init: function(event, data) {
app.ui.sectionLength[id] = data.items;
app.$ui.section[i].$content.css({
height: 40 + data.items * 16 + 'px'
});
app.$ui.sectionList[i].css({
height: 16 + data.items * 16 + 'px'
});
resizeSections();
},
paste: function(event, data) {
app.$ui.list.triggerEvent('paste', data);
},
select: function(event, data) {
// fixme: duplicated
if (data.ids.length) {
app.$ui.sectionList.forEach(function($list, i_) {
i != i_ && $list.options('selected', []);
});
UI.set({list: data.ids[0]});
URL.set('?find=list:' + data.ids[0]);
} else {
UI.set({list: ''});
URL.set('');
}
}
});
return that;
},
mainMenu: function() {
var isGuest = app.user.group == 'guest',
that = new Ox.MainMenu({
extras: [
$('
').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: 'tos', 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 Movies' }
] },
{ 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 Movie to List...', 'Add Selected Movies 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 Movies', items: [
{ group: 'viewmovies', min: 0, max: 1, items: $.map(app.config.listViews, function(view, i) {
//alert(JSON.stringify([app.user.ui.list, app.user.ui.lists]))
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 Movie', 'Open Movies'], 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 Movies', disabled: true, keyboard: 'shift m' }
]},
{ id: 'sortMenu', title: 'Sort', items: [
{ id: 'sortmovies', title: 'Sort Movies by', items: [
{ group: 'sortmovies', min: 1, max: 1, items: $.map(app.config.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 Movies', 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.config.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 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 = getSortOperator(id);
app.$ui.mainMenu.checkItem('sortMenu_ordermovies_' + (operator === '' ? 'ascending' : 'descending'));
app.$ui.sortSelect.selectItem(id);
//alert(id + ' ' + operator)
app.$ui.list.sortList(id, operator);
URL.set(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 = ui.accountDialog('register').open();
} else if (data.id == 'loginlogout') {
app.$ui.accountDialog = (app.user.group == 'guest' ?
ui.accountDialog('login') : ui.accountLogoutDialog()).open();
} else if (data.id == 'places') {
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(Query.toObject()),
'findQuery: ' + JSON.stringify(app.user.ui.findQuery),
'listQuery: ' + JSON.stringify(app.user.ui.listQuery)
].join('
')),
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;
},
mainPanel: function() {
var that = new Ox.SplitPanel({
elements: [
{
collapsible: true,
collapsed: !app.user.ui.showSidebar,
element: app.$ui.leftPanel = ui.leftPanel(),
resizable: true,
resize: [192, 256, 320, 384],
size: app.user.ui.sidebarSize
},
{
element: app.$ui.rightPanel = ui.rightPanel()
}
],
orientation: 'horizontal'
})
return that;
},
publicListsDialog: function() { // fixme: unused
var that = new Ox.Dialog({
buttons: [
new Ox.Button({
id: 'done',
title: 'Done'
}).bindEvent({
click: function() {
that.close();
}
})
],
content: ui.publicListsList(),
height: 320,
keys: {enter: 'close', escape: 'close'},
padding: 0,
title: 'Public Lists',
width: 420
})
.css({
position: 'absolute'
});
return that;
},
rightPanel: function() {
var that = new Ox.SplitPanel({
elements: [
{
element: app.$ui.toolbar = ui.toolbar(),
size: 24
},
{
element: app.$ui.contentPanel = ui.contentPanel()
},
{
element: app.$ui.statusbar = 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.triggerResize();
}
} 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 - (app.user.ui.showAnnotations * app.user.ui.annotationsSize) - 1
});
}
});
return that;
},
sectionbar: function(mode) {
var that = new Ox.Bar({
size: 24
})
.append(
mode == 'buttons' ?
app.$ui.sectionButtons = ui.sectionButtons() :
app.$ui.sectionSelect = ui.sectionSelect()
);
that.toggle = function() {
};
return that;
},
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'
});
return that;
},
sectionList: function(id) {
var i = ['my', 'public', 'featured'].indexOf(id), // fixme: find a better way
that = new Ox.TextList({
columns: [
{
format: function() {
return $('
').attr({
src: 'static/oxjs/build/png/ox.ui/icon16.png'
});
},
id: 'user',
operator: '+',
visible: true,
width: 16
},
{
format: function(value) {
return value.split('/').join(': ');
},
id: 'id',
operator: '+',
unique: true,
visible: id == 'public',
width: app.user.ui.sidebarWidth - 88
},
{
editable: function(data) {
return data.user == app.user.username;
},
id: 'name',
input: {
autovalidate: autovalidateListname
},
operator: '+',
visible: id != 'public',
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 $('
')
.attr({
src: 'static/oxjs/build/png/ox.ui.' + Ox.theme() +
'/symbolFind.png'
})
.css({
opacity: value == 'static' ? 0.1 : 1
});
},
id: 'type',
operator: '+',
visible: true,
width: 16
},
{
clickable: id == 'my',
format: function(value) {
//var symbols = {private: 'Publish', public: 'Publish', featured: 'Star'};
return $('
')
.attr({
src: 'static/oxjs/build/png/ox.ui.' + Ox.theme() + '/symbol'
+ (value == 'featured' ? 'Star' : 'Publish') + '.png'
})
.css({
opacity: value == 'private' ? 0.1 : 1
})
},
id: 'status',
operator: '+',
visible: true,
width: 16
}
],
max: 1,
min: 0,
pageLength: 1000,
request: function(data, callback) {
var query;
if (id == 'my') {
query = {conditions: [
{key: 'user', value: app.user.username, operator: '='},
{key: 'status', value: 'featured', operator: '!'}
], operator: '&'};
} else if (id == 'public') {
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);
},
sort: [
{key: 'position', operator: '+'}
],
sortable: id == 'my' || id == 'public' || app.user.group == '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.sectionList[i];
if (data.key == 'type') {
var $dialog = new Ox.Dialog({
buttons: [
new Ox.Button({
id: 'cancel',
title: 'Cancel'
}).bindEvent('click', function() {
$dialog.close();
}),
new Ox.Button({
id: 'save',
title: 'Save'
}).bindEvent('click', function() {
$dialog.close();
})
],
content: new Ox.Element('div').html('...'),
height: 200,
keys: {enter: 'save', escape: 'cancel'},
title: 'Advanced Find',
width: 640
}).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.sectionList[i];
URL.set('');
$list.options({selected: []});
if (id == 'my') {
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]];
UI.set({lists: app.user.ui.lists});
Ox.Request.emptyCache(); // fixme: remove
$list.reloadList();
});
} else if (id == 'public') {
pandora.api.unsubscribeFromList({
id: data.ids[0]
}, function(result) {
Ox.Request.emptyCache(); // fixme: remove
$list.reloadList();
});
} else if (id == 'featured' && app.user.group == '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.emptyCache(); // fixme: remove
app.$ui.sectionList[
result.data.user == app.user.username ? 0 : 1
].reloadList();
}
$list.reloadList();
});
}
},
init: function(event, data) {
app.ui.sectionLength[id] = data.items; // fixme: why by id, not by i?
app.$ui.section[i].$content.css({
height: data.items * 16 + 'px'
});
app.$ui.sectionList[i].css({
height: data.items * 16 + 'px'
});
resizeSections();
},
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) {
var $list = app.$ui.sectionList[i];
if (data.ids.length) {
app.$ui.sectionList.forEach(function($list, i_) {
i != i_ && $list.options('selected', []);
});
URL.set('?find=list:' + data.ids[0]);
} else {
URL.set('');
}
},
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.sectionList[i].value(data.id, 'name', result.data.name);
app.$ui.sectionList[i].value(data.id, 'id', result.data.id);
URL.set('?find=list:' + result.data.id);
}
});
}
});
return that;
},
sections: function() {
var that = new Ox.Element()
.css({overflowX: 'hidden', overflowY: 'auto'})
.bindEvent({
resize: function(event, data) {
resizeSections();
}
});
var counter = 0;
//var $sections = [];
app.$ui.section = [];
app.$ui.sectionList = [];
$.each(app.user.ui.sections, function(i, id) {
var extras;
if (id == 'my' && app.user.group != '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.sectionList[i],
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;
UI.set(['lists', id].join('|'), app.config.user.ui.lists['']);
URL.set('?find=list:' + id)
Ox.Request.emptyCache(); // fixme: remove
$list.reloadList().bindEvent({load: load});
function load(event, data) {
$list.gainFocus()
.options({selected: [id]})
.editCell(id, 'name');
$list.unbindEvent({load: load}) // fixme: need bindEventOnce
}
});
}
}
})];
} else if (id == 'public' && app.user.group != 'guest') {
extras = [new Ox.Button({
selectable: true,
style: 'symbol',
title: 'Edit',
tooltip: 'Manage Favorite Lists',
type: 'image'
})
.bindEvent({
change: function(event, data) {
Ox.Request.emptyCache(); // fixme: remove
app.ui.showPublicListsBrowser = !app.ui.showPublicListsBrowser;
if (app.ui.showPublicListsBrowser) {
app.$ui.sectionList[1].replaceWith(app.$ui.publicListsBrowser = ui.listsBrowser('public'));
} else {
app.$ui.publicListsBrowser.replaceWith(app.$ui.sectionList[1] = ui.sectionList('public'));
}
resizeSections();
}
})];
} else if (id == 'featured' && app.user.group == 'admin') {
extras = [new Ox.Button({
selectable: true,
style: 'symbol',
title: 'Edit',
tooltip: 'Manage Featured Lists',
type: 'image'
})
.bindEvent({
change: function(event, data) {
Ox.Request.emptyCache(); // fixme: remove
app.ui.showFeaturedListsBrowser = !app.ui.showFeaturedListsBrowser;
if (app.ui.showFeaturedListsBrowser) {
app.$ui.sectionList[2].replaceWith(app.$ui.featuredListsBrowser = ui.listsBrowser('featured'));
} else {
app.$ui.featuredListsBrowser.replaceWith(app.$ui.sectionList[2] = ui.sectionList('featured'));
}
resizeSections();
}
})];
}
app.$ui.section[i] = new Ox.CollapsePanel({
id: id,
collapsed: !app.user.ui.showSection[id],
extras: extras,
size: 16,
title: Ox.getObjectById(app.config.sections, id).title
})
.bindEvent({
click: function(event, data) {
var $list = app.$ui.sectionList[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;
URL.set('?find=list:' + id)
Ox.Request.emptyCache(); // fixme: remove
$list.reloadList().bindEvent({load: load});
function load(event, data) {
$list.gainFocus()
.options({selected: [id]})
.editCell(id, 'name');
$list.unbindEvent({load: load}) // fixme: need bindEventOnce
}
});
} else if (data.id == 'browse') {
app.$ui.sectionList[1].replaceWith(app.$ui.publicLists = ui.publicLists());
app.ui.showAllPublicLists = true;
}
},
toggle: function(event, data) {
data.collapsed && app.$ui.sectionList[i].loseFocus();
UI.set(['showSection', id].join('|'), !data.collapsed);
resizeSections();
}
});
//$sections.push(app.$ui.section[i]);
app.$ui.sectionList[i] = ui.sectionList(id)
.bindEvent({init: init})
.appendTo(app.$ui.section[i].$content);
function init(event, data) {
Ox.print('init', i, counter)
if (++counter == 3) {
$.each(app.$ui.section, function(i, $section) {
that.append($section);
});
resizeSections();
//selectList(); fixme: doesn't work
}
app.$ui.sectionList[i].unbindEvent({init: init}); // fixme: need bindEventOnce
}
});
that.toggle = function() {
}
return that;
},
sectionSelect: function() {
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'
});
return that;
},
sortSelect: function() {
var that = new Ox.Select({
id: 'sortSelect',
items: $.map(app.config.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 = 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'));
//alert(id + ' ' + operator)
app.$ui.list.sortList(id, operator);
URL.set(Query.toString());
}
});
return that;
},
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;
},
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;
},
toolbar: function() {
var that = new Ox.Bar({
size: 24
}).css({
zIndex: 2 // fixme: remove later
});
app.user.ui.item && that.append(
app.$ui.backButton = ui.backButton()
);
that.append(
app.$ui.viewSelect = ui.viewSelect()
);
!app.user.ui.item && that.append(
app.$ui.sortSelect = ui.sortSelect()
);
that.append(
app.$ui.findElement = ui.findElement()
);
that.display = function() {
app.$ui.rightPanel.replace(0, app.$ui.toolbar = ui.toolbar()); // fixme: remove later
}
return that;
},
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.title
});
}),
width: !app.user.ui.item ? 144 : 96
})
.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);
//app.$ui.contentPanel.replace(1, app.$ui.list = ui.list(id));
UI.set(['lists', app.user.ui.list, 'listView'].join('|'), id);
URL.set(Query.toString());
} : function(event, data) {
var id = data.selected[0].id;
UI.set({itemView: id});
// fixme: URL.set() here
app.$ui.contentPanel.replace(1, app.$ui.item = ui.item());
}
});
return that;
}
}
function autovalidateCode(value, blur, callback) {
value = $.map(value.toUpperCase().split(''), function(v) {
return /[0-9A-Z]/(v) ? v : null;
}).join('');
callback(value);
}
function autovalidateEmail(value, blur, callback) {
value = $.map(value.toLowerCase().split(''), function(v, i) {
return /[0-9a-z\.\+\-_@]/(v) ? v : null;
}).join('');
callback(value);
}
function autovalidateListname(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')(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);
}
function autovalidateUsername(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)) ? '' : '\-_') + ']')(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);
}
function enterFullscreen() {
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 - app.ui.scrollbarSize) + '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
})
}
function exitFullscreen() {
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 - app.ui.scrollbarSize) + 'px' // fixme: rightPanel.size(0, 0) doesn't preserve negative top of browser
});
app.user.ui.showMovies && app.$ui.contentPanel.size(0, 112 + app.ui.scrollbarSize);
}
function getAlignment(key) { // fixme: make static
return ['person', 'string', 'text', 'title'].indexOf(
Ox.getObjectById(app.config.sortKeys, key).type
) > -1 ? 'left' : 'right';
}
function getListData() {
var data = {};
if (app.user.ui.list) {
var section = app.$ui.sectionList[0].options('selected')[0] == app.user.ui.list ? 0 : 2;
data = app.$ui.sectionList[section].value(app.user.ui.list);
}
data.editable = data.user == app.user.username && data.type == 'static';
return data;
}
function getGroupWidth(pos, panelWidth) { // fixme: don't pass panelWidth
var width = {};
width.list = Math.floor(panelWidth / 5) + (panelWidth % 5 > pos);
width.column = width.list - 40 - app.ui.scrollbarSize;
return width;
}
function getSectionsHeight() {
var height = 48;
$.each(app.user.ui.showSection, function(id, show) {
height += show * app.ui.sectionLength[id] * 16;
if (id == 'public' && app.ui.showPublicListsBrowser) {
height += show * 40;
} else if (id == 'featured' && app.ui.showFeaturedListsBrowser) {
height += show * 40;
}
});
return height;
}
function getSectionsWidth() {
var width = app.user.ui.sidebarSize;
// fixme: don't use height(), look up in splitpanels
Ox.print(getSectionsHeight(), '>', app.$ui.leftPanel.height() - 24 - 1 - app.$ui.info.height())
if (getSectionsHeight() > app.$ui.leftPanel.height() - 24 - 1 - app.$ui.info.height()) {
width -= app.ui.scrollbarSize;
}
Ox.print('width', width)
return width;
}
function getSortOperator(key) { // fixme: make static
return ['person', 'string', 'text', 'title'].indexOf(
Ox.getObjectById(app.config.sortKeys, key).type
) > -1 ? '' : '-';
}
function reloadGroups(i) {
var query = Query.toObject();
app.$ui.list.options({
request: 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({
request: function(data, callback) {
delete data.keys;
//alert(i_ + " Query.toObject " + JSON.stringify(Query.toObject(group_.id)))
return pandora.api.find($.extend(data, {
group: group_.id,
query: Query.toObject(group_.id)
}), callback);
}
});
}
});
history.pushState({}, '', Query.toString(query));
}
function reloadList() {
Ox.print('reloadList')
var listData = getListData();
Ox.Request.emptyCache(); // fixme: remove
app.$ui.groups.forEach(function($group) {
$group.reloadList();
});
app.$ui.list.bindEvent({
init: function(event, data) {
app.$ui.sectionList[listData.status == 'featured' ? 2 : 0]
.value(listData.id, 'items', data.items);
},
load: load
})
.reloadList();
function load(event, data) {
app.$ui.list.gainFocus().options({selected: [data.items]});
app.$ui.list.unbindEvent({load: load}); // fixme: need bindEventOnce
}
}
function resizeGroups(width) {
var widths = $.map(app.ui.groups, function(v, i) {
return 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);
});
}
function resizeWindow() {
resizeSections();
if (app.user.ui.item == '') {
app.$ui.list.size();
resizeGroups(app.$ui.rightPanel.width());
if (app.user.ui.listView == 'map') {
app.$ui.map.triggerResize();
}
} else {
//Ox.print('app.$ui.window.resize');
app.$ui.browser.scrollToSelection();
app.user.ui.itemView == 'player' && app.$ui.player.options({
// fixme: duplicated
height: app.$ui.contentPanel.size(1),
width: app.$ui.document.width() - app.$ui.mainPanel.size(0) - 1
});
app.user.ui.itemView == 'timeline' && app.$ui.editor.options({
// fixme: duplicated
height: app.$ui.contentPanel.size(1),
width: app.$ui.document.width() - app.$ui.mainPanel.size(0) - 1 -
(app.user.ui.showAnnotations * app.user.ui.annotationsSize) - 1
});
}
}
function resizeSections() {
var width = getSectionsWidth(),
columnWidth = {user: parseInt((width - 88) * 0.4)};
columnWidth.name = (width - 88) - columnWidth.user;
Ox.print('sectionsWidth', width)
app.$ui.sectionList.forEach(function($list, i) {
var id = ['my', 'public', 'featured'][i], // fixme: find a better way
height;
app.$ui.section[i].css({width: width + 'px'});
$list.css({width: width + 'px'});
if (
(i == 1 && app.ui.showPublicListsBrowser) ||
(i == 2 && app.ui.showFeaturedListsBrowser)
) {
$list.resizeColumn('user', columnWidth.user)
.resizeColumn('name', columnWidth.name);
} else {
$list.resizeColumn(i == 1 ? 'id' : 'name', width - 88);
}
if (!app.user.ui.showSection[id]) {
app.$ui.section[i].update();
}
});
}
function selectList() {
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 list, section = -1;
if (result.data.items.length) {
list = result.data.items[0]
if (list.user == app.user.username) {
section = list.status == 'featured' ? 2 : 0
} else {
section = 1;
}
}
if (section > -1) {
app.$ui.sectionList[section]
.options('selected', [app.user.ui.list])
.gainFocus();
} else {
app.user.ui.list = '';
//app.user.ui.listQuery.conditions = []; // fixme: Query should read from ui.list, and not need ui.listQuery to be reset
//URL.set(Query.toString());
}
})
}
}
function validateUser(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
});
};
}
var 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) {
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] && UI.set(
['lists', list].join('|'), app.config.user.ui.lists['']
);
}
UI.set({list: list});
//Ox.print('user.ui.findQuery', app.user.ui.findQuery)
}
if ('sort' in query) {
sort = query.sort.split(',')
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('+', '') : getSortOperator(key);
return {
key: key,
operator: operator
};
}));
}
if ('view' in query) {
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)
return '?' + Ox.serialize({
find: constructFind(Query.toObject()),
sort: app.user.ui.lists[app.user.ui.list].sort[0].operator +
app.user.ui.lists[app.user.ui.list].sort[0].key,
view: app.user.ui.lists[app.user.ui.list].listView
});
}
};
})();
var UI = (function() {
return {
set: function(obj) {
if (arguments.length == 2) {
var obj_ = {};
obj_[arguments[0]] = arguments[1];
obj = obj_;
}
$.each(obj, function(key, val) {
Ox.print('key', key, 'val', val)
keys = key.split('|');
if (keys.length == 1) {
app.user.ui[keys[0]] = val;
} else if (keys.length == 2) {
app.user.ui[keys[0]][keys[1]] = val;
} else if (keys.length == 3) {
app.user.ui[keys[0]][keys[1]][keys[2]] = val;
} else if (keys.length == 4) {
app.user.ui[keys[0]][keys[1]][keys[2]][keys[3]] = val;
} else if (keys.length == 5) {
app.user.ui[keys[0]][keys[1]][keys[2]][keys[3]][keys[4]] = val;
} else if (keys.length == 6) {
app.user.ui[keys[0]][keys[1]][keys[2]][keys[3]][keys[4]][keys[5]] = val;
}
});
pandora.api.setUI(obj);
}
}
}());
var URL = (function() {
var old = {
user: {
ui: {}
}
},
regexps = {
'^\\?': function(url) {
Query.fromString(url);
UI.set({
section: 'items',
item: ''
});
},
'^(about|faq|home|news|software|terms|tour)$': function(url) {
UI.set({
section: 'site',
sitePage: url
});
},
'^(|find)$': function() {
Query.fromString('?find='); // fixme: silly hack
UI.set({
section: 'items',
item: ''
});
},
'^(calendar|calendars|clips|icons|flow|map|maps|timelines)$': function() {
UI.set({
section: 'items',
item: ''
});
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(
'^(calendar|clips|files|info|map|player|statistics|timeline)$'
)(split[1]) || app.user.ui.itemView;
UI.set({
section: 'items',
item: item,
itemView: view
});
},
'^texts$': function() {
UI.set({
section: 'texts'
});
},
'^admin$': function() {
UI.set({
section: 'admin'
});
}
};
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
URL.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(url)) {
Ox.print('URL re ' + re)
fn(url);
return false;
}
});
},
update: function() {
URL.parse();
if (app.user.ui.section == 'items') {
if (!old.user.ui.item) {
if (!app.user.ui.item) {
app.$ui.mainPanel.replace(1, app.$ui.rightPanel = ui.rightPanel());
//app.$ui.contentPanel.replace(1, ui.list());
} else {
app.$ui.mainPanel.replace(1, app.$ui.rightPanel = ui.rightPanel());
//app.$ui.rightPanel.replace(0, app.$ui.toolbar = ui.toolbar());
//ui.item().display();
}
} else {
if (!app.user.ui.item) {
app.$ui.mainPanel.replace(1, app.$ui.rightPanel = ui.rightPanel());
//ui.list(app.user.ui.listView).display();
} else {
app.$ui.contentPanel.replace(1, ui.item());
}
}
}
delete old.user.ui;
}
}
}());
var url = function(url) { // fixme: unused
var currentURL = document.location.pathname.substr(1) + document.location.hash,
match = false;
regexps = {
'^[0-9A-Z]': function() {
var split = url.split('/'),
id = split[0],
view = split[1] || app.user.ui.itemView;
ui.item(id, view);
}
};
if (!url)
url = currentURL;
else {
if (url != currentURL) {
var title = document.title + ' ' + url;
history.pushState({}, title, url);
} else {
//FIXME: this is a workaround since open gets called twice
// due to a bug with double click
//Ox.print('ignore double call of app.url, double click need to be fixed');
return;
}
}
$.each(regexps, function(re, fn) {
re = new RegExp(re);
if (re(url)) {
fn();
match = true;
return false;
}
});
if (!match) {
Query.fromString(location.hash.substr(1));
app.$ui.rightPanel.replace(1, ui.contentPanel());
}
}
load();
});