openmedialibrary/static/js/utils.js

1076 lines
37 KiB
JavaScript
Raw Normal View History

2014-05-12 12:57:47 +00:00
oml.addList = function() {
2014-05-18 23:24:04 +00:00
// addList(isSmart, isFrom[, name[, callback]])
// or addList(list) [=duplicate]
2014-05-12 12:57:47 +00:00
var args = arguments,
isDuplicate = args.length == 1,
2014-05-18 23:24:04 +00:00
isSmart, isFrom, name, callback,
list, listData, data,
ui = oml.user.ui,
2014-05-12 23:43:27 +00:00
username = oml.user.preferences.username;
2014-05-17 14:42:46 +00:00
Ox.Request.clearCache('getLists');
2014-05-12 12:57:47 +00:00
oml.api.getLists(function(result) {
var lists = result.data.lists,
2014-05-12 23:43:27 +00:00
listNames = lists.filter(function(list) {
return list.user = username;
}).map(function(list) {
2014-05-12 12:57:47 +00:00
return list.name;
}),
query;
if (!isDuplicate) {
isSmart = args[0];
isFrom = args[1];
2014-05-18 23:24:04 +00:00
name = args[2] || Ox._('Untitled');
callback = args[3];
2014-05-12 12:57:47 +00:00
data = {
2014-05-18 23:24:04 +00:00
name: oml.getValidName(name, listNames),
2014-05-12 12:57:47 +00:00
type: !isSmart ? 'static' : 'smart'
};
2014-05-14 09:57:11 +00:00
if (!isSmart) {
if (isFrom) {
2014-05-12 12:57:47 +00:00
data.items = ui.listSelection;
2014-05-14 09:57:11 +00:00
}
} else {
if (!isFrom) {
data.query = oml.config.user.ui.find;
2014-05-12 12:57:47 +00:00
} else {
data.query = ui.find;
}
}
addList();
} else {
list = args[0];
listData = Ox.getObjectById(Ox.flatten(Ox.values(lists)), list);
data = Ox.extend({
2014-05-18 23:24:04 +00:00
name: oml.getValidName(listData.name, listNames),
2014-05-12 12:57:47 +00:00
type: listData.type
}, listData.query ? {
query: listData.query
} : {});
if (!data.query) {
var query = {
conditions: [{key: 'list', operator: '==', value: list}],
operator: '&'
};
oml.api.find({query: query}, function(result) {
if (result.data.items) {
oml.api.find({
query: query,
keys: ['id'],
sort: [{key: 'id', operator: '+'}],
range: [0, result.data.items]
}, function(result) {
data.items = result.data.items.map(function(item) {
return item.id;
});
addList();
});
} else {
addList();
}
});
} else {
addList();
}
}
});
function addList() {
oml.api.addList(data, function(result) {
var list = result.data.id,
$folderList = oml.$ui.folderList[0];
oml.$ui.folder[0].options({collapsed: false}); // FIXME: SET UI!
// FIXME: DOESN'T WORK
2014-05-18 23:24:04 +00:00
if (
!oml.$ui.importExportDialog
|| !oml.$ui.importExportDialog.is(':visible')
) {
$folderList
.bindEventOnce({
load: function() {
$folderList
.gainFocus()
.options({selected: [list]});
oml.UI.set({
find: {
conditions: [{
key: 'list',
operator: '==',
value: list
}],
operator: '&'
}
});
oml.$ui.listDialog = oml.ui.listDialog().open();
}
});
}
2014-05-17 14:42:46 +00:00
oml.$ui.folders.updateOwnLists();
2014-05-18 23:24:04 +00:00
callback && callback();
2014-05-12 12:57:47 +00:00
});
}
};
oml.clearFilters = function() {
var ui = oml.user.ui,
find = Ox.clone(ui.find, true),
indices = ui._filterState.map(function(filterState) {
return filterState.index;
}).filter(function(index) {
return index > -1;
});
find.conditions = find.conditions.filter(function(condition, index) {
return !Ox.contains(indices, index);
});
oml.UI.set({find: find});
};
2016-01-16 08:40:20 +00:00
oml.autovalidateEmail = function(value, blur, callback) {
value = value.toLowerCase().split('').map(function(v, i) {
return /[0-9a-z\.\+\-_@]/.test(v) ? v : null;
}).join('').slice(0, 255);
callback({valid: Ox.isValidEmail(value), value: value});
};
2014-05-19 18:12:02 +00:00
oml.clickLink = function(e) {
if (
e.target.hostname == document.location.hostname
&& !Ox.startsWith(e.target.pathname, '/static')
) {
oml.URL.push(e.target.pathname, true);
} else {
oml.openLink(e.target.href);
}
};
2014-05-21 00:02:39 +00:00
oml.createLinks = function($element) {
function isExternalLink(target) {
return target.hostname != document.location.hostname
|| Ox.startsWith(target.pathname, '/static');
}
$element.on({
click: function(e) {
var $target = $(e.target);
if ($target.is('a')) {
e.preventDefault();
if (isExternalLink(e.target)) {
oml.openLink(e.target.href);
} else {
oml.clickLink(e);
}
}
return false;
}
});
};
2014-05-12 12:57:47 +00:00
(function() {
oml.doHistory = function(action, items, targets, callback) {
items = Ox.makeArray(items);
targets = Ox.makeArray(targets);
if (action == 'copy' || action == 'paste') {
addItems(items, targets[0], addToHistory);
} else if (action == 'cut' || action == 'delete') {
removeItems(items, targets[0], addToHistory);
} else if (action == 'move') {
removeItems(items, targets[0], function() {
addItems(items, targets[1], addToHistory);
});
}
function addToHistory(result, addedItems) {
var actions = {
copy: 'Copying',
cut: 'Cutting',
'delete': 'Deleting',
move: 'Moving',
paste: 'Pasting'
},
length = items.length,
text = Ox._(actions[action]) + ' ' + (
length == 1 ? 'Book' : 'Books'
);
oml.history.add({
action: action,
items: action == 'cut' || action == 'delete' ? [items]
: action == 'copy' || action == 'paste' ? [addedItems]
: [items, addedItems], // move
positions: [],
targets: targets,
text: text
});
callback(result);
}
};
oml.redoHistory = function(callback) {
var object = oml.history.redo();
if (object) {
if (object.action == 'copy' || object.action == 'paste') {
addItems(object.items[0], object.targets[0], done);
} else if (object.action == 'cut' || object.action == 'delete') {
removeItems(object.items[0], object.targets[0], done);
} else if (object.action == 'move') {
removeItems(object.items[0], object.targets[0], function() {
addItems(object.items[1], object.targets[1], done);
});
}
}
function done() {
doneHistory(object, callback);
}
};
oml.undoHistory = function(callback) {
var object = oml.history.undo();
if (object) {
if (object.action == 'copy' || object.action == 'paste') {
removeItems(object.items[0], object.targets[0], done);
} else if (object.action == 'cut' || object.action == 'delete') {
addItems(object.items[0], object.targets[0], done);
} else if (object.action == 'move') {
removeItems(object.items[1], object.targets[1], function() {
addItems(object.items[0], object.targets[0], done);
});
}
}
function done() {
doneHistory(object, callback);
}
};
function addItems(items, target, callback) {
oml.api.find({
query: {
conditions: [{
key: 'list',
operator: '==',
value: target
}],
operator: '&'
},
positions: items
}, function(result) {
var existingItems = Object.keys(result.data.positions),
addedItems = items.filter(function(item) {
return !Ox.contains(existingItems, item);
});
if (addedItems.length) {
oml.api.addListItems({
items: addedItems,
list: target
}, function(result) {
2014-05-17 23:14:29 +00:00
Ox.Request.clearCache();
2014-05-12 12:57:47 +00:00
callback(result, addedItems);
});
2014-05-12 12:57:47 +00:00
} else {
callback(null, []);
}
});
}
function doneHistory(object, callback) {
var list, listData, ui = oml.user.ui;
Ox.Request.clearCache('find');
object.targets.filter(function(list) {
return list != ui._list;
}).forEach(function(list) {
listData = oml.getListData(list);
oml.api.find({
query: {
conditions: [{
key: 'list',
operator: '==',
value: list
}],
operator: '&'
}
}, function(result) {
oml.$ui.folderList[listData.folder].value(
list, 'items', result.data.items
);
});
});
if (Ox.contains(object.targets, ui._list)) {
// FIXME: Why is this timeout needed?
2016-01-12 08:52:20 +00:00
setTimeout(oml.reloadLists, 250);
2014-05-12 12:57:47 +00:00
}
callback && callback();
}
function removeItems(items, target, callback) {
oml.api.removeListItems({
items: items,
list: target
}, callback);
}
}());
oml.enableDragAndDrop = function($list, canMove) {
var $tooltip = Ox.Tooltip({
animate: false
}),
drag = {},
scrollInterval,
2014-05-25 14:05:26 +00:00
ui = oml.user.ui;
2014-05-12 12:57:47 +00:00
$list.bindEvent({
draganddropstart: function(data) {
var $lists = oml.$ui.libraryList.concat(oml.$ui.folderList);
drag.action = 'copy';
drag.ids = $list.options('selected');
drag.item = drag.ids.length == 1
2016-01-05 05:14:50 +00:00
? Ox.decodeHTMLEntities($list.value(drag.ids[0], 'title'))
2014-05-12 12:57:47 +00:00
: drag.ids.length;
drag.source = oml.getListData();
drag.targets = {};
$lists.forEach(function($list) {
$list.addClass('OxDroppable').find('.OxItem').each(function() {
var $item = $(this),
id = $item.data('id'),
data = oml.getListData(id);
drag.targets[id] = Ox.extend(data, {
editable: data.editable || (
data.type == 'library'
2014-05-25 14:05:26 +00:00
&& drag.source.user != ''
&& data.user == ''
2014-05-12 12:57:47 +00:00
),
selected: data.id == ui._list
}, data);
if (!drag.targets[id].selected && drag.targets[id].editable) {
$item.addClass('OxDroppable');
}
});
});
$tooltip.options({title: getTitle()}).show(data.event);
2014-09-29 13:17:59 +00:00
Ox.$window.on({
2014-05-12 12:57:47 +00:00
keydown: keydown,
keyup: keyup
});
},
draganddrop: function(data) {
var event = data.event;
$tooltip.options({
title: getTitle(event)
}).show(event);
if (scrollInterval && !isAtListsTop(event) && !isAtListsBottom(event)) {
clearInterval(scrollInterval);
scrollInterval = 0;
}
},
draganddroppause: function(data) {
var event = data.event, scroll, title,
ui = oml.user.ui,
$parent, $grandparent, $panel;
if (!ui.showSidebar) {
if (event.clientX < 16 && event.clientY >= 44
&& event.clientY < window.innerHeight - 16
) {
2014-09-25 11:39:05 +00:00
oml.$ui.mainPanel.toggleElement(0);
2014-05-12 12:57:47 +00:00
}
} else {
$parent = $(event.target).parent();
$grandparent = $parent.parent();
$panel = $parent.is('.OxCollapsePanel') ? $parent
: $grandparent.is('.OxCollapsePanel') ? $grandparent
: null;
if ($panel) {
title = $panel.children('.OxBar').children('.OxTitle')
.html().split(' ')[0].toLowerCase();
if (!ui.showFolder[title]) {
2014-09-29 13:17:59 +00:00
Ox.$elements[$panel.data('oxid')].options({
2014-05-12 12:57:47 +00:00
collapsed: false
});
}
}
if (!scrollInterval) {
scroll = isAtListsTop(event) ? -16
: isAtListsBottom(event) ? 16
: 0
if (scroll) {
scrollInterval = setInterval(function() {
oml.$ui.folders.scrollTop(
oml.$ui.folders.scrollTop() + scroll
);
}, 100);
}
}
}
},
draganddropenter: function(data) {
var $parent = $(data.event.target).parent(),
$item = $parent.is('.OxItem') ? $parent : $parent.parent(),
$list = $item.parent().parent().parent().parent();
if ($list.is('.OxDroppable')) {
$item.addClass('OxDrop');
drag.target = drag.targets[$item.data('id')];
} else {
drag.target = null;
}
},
draganddropleave: function(data) {
var $parent = $(data.event.target).parent(),
$item = $parent.is('.OxItem') ? $parent : $parent.parent();
if ($item.is('.OxDroppable')) {
$item.removeClass('OxDrop');
drag.target = null;
}
},
draganddropend: function(data) {
var targets;
2014-09-29 13:17:59 +00:00
Ox.$window.off({
2014-05-12 12:57:47 +00:00
keydown: keydown,
keyup: keyup
});
if (
drag.target && drag.target.editable && !drag.target.selected
&& (drag.action == 'copy' || drag.source.editable)
) {
var targets = drag.action == 'copy' ? drag.target.id
: [oml.user.ui._list, drag.target.id];
oml.doHistory(drag.action, data.ids, targets, function() {
Ox.Request.clearCache('find');
oml.api.find({
query: {
conditions: [{
key: 'list',
operator: '==',
value: drag.target.id
}],
operator: '&'
}
}, function(result) {
2014-05-12 23:43:27 +00:00
/* FIXME
2014-05-12 12:57:47 +00:00
oml.$ui.folderList[drag.target.folder].value(
drag.target.id, 'items', result.data.items
);
2014-05-12 23:43:27 +00:00
*/
2014-05-12 12:57:47 +00:00
cleanup(250);
});
2014-05-17 14:42:46 +00:00
oml.$ui.folders.updateItems();
if (drag.action == 'move') {
oml.$ui.list.updateElement();
}
2014-05-12 12:57:47 +00:00
});
} else {
cleanup()
}
}
});
function cleanup(ms) {
ms = ms || 0;
drag = {};
clearInterval(scrollInterval);
scrollInterval = 0;
setTimeout(function() {
$('.OxDroppable').removeClass('OxDroppable');
$('.OxDrop').removeClass('OxDrop');
$tooltip.hide();
}, ms);
}
function getTitle() {
var image, text,
actionText = drag.action == 'copy' ? (
2014-05-25 14:05:26 +00:00
drag.source.user == '' ? 'copy' : 'download'
2014-05-12 12:57:47 +00:00
) : 'move',
itemText = Ox.isString(drag.item)
? '"' + Ox.encodeHTMLEntities(Ox.truncate(drag.item, 32)) + '"'
: Ox._('{0} books', [drag.item]),
targetText;
if (drag.action == 'move') {
2014-05-25 14:05:26 +00:00
if (drag.source.user != '') {
2014-05-12 12:57:47 +00:00
text = Ox._('You can only remove books<br>from your own lists.');
} else if (drag.source.type == 'library') {
text = Ox._('You cannot move books<br>out of your library.');
} else if (drag.source.type == 'smart') {
text = Ox._('You cannot move books<br>out of a smart list.');
}
} else if (drag.target) {
targetText = drag.target.type == 'libraries' ? Ox._('a library')
: drag.target.type == 'library' ? Ox._('your library')
: Ox._('the list "{0}"', [Ox.encodeHTMLEntities(Ox.truncate(drag.target.name, 32))]);
if (
(
drag.target.type == 'library'
2014-05-25 14:05:26 +00:00
&& drag.source.user == ''
&& drag.target.user == ''
2014-05-12 12:57:47 +00:00
)
|| drag.target.selected
) {
text = Ox._('{0}<br>is already in {1}.', [
Ox._(itemText[0] == '"' ? '' : 'These ') + itemText,
targetText
]);
2014-05-25 14:05:26 +00:00
} else if (drag.target.user != '') {
2014-05-12 12:57:47 +00:00
text = Ox._(
'You can only {0} books<br>to your own {1}.',
[actionText, drag.target.type == 'library' ? 'library' : 'lists']
);
} else if (drag.target.type == 'smart') {
text = Ox._('You cannot {0} books<br>to a smart list.', [actionText]);
}
}
if (text) {
image = 'symbolClose'
} else {
image = drag.action == 'copy' ? (
2014-05-25 14:05:26 +00:00
drag.source.user == '' ? 'symbolAdd' : 'symbolDownload'
2014-05-12 12:57:47 +00:00
) : 'symbolRemove',
text = Ox._(Ox.toTitleCase(actionText)) + ' ' + (
Ox.isString(drag.item)
? '"' + Ox.encodeHTMLEntities(Ox.truncate(drag.item, 32)) + '"'
: drag.item + ' ' + 'books'
) + '<br>' + (
drag.target && drag.target.editable && !drag.target.selected
? Ox._('to {0}.', [targetText])
2014-05-25 14:05:26 +00:00
: drag.source.user == ''
2014-05-12 12:57:47 +00:00
? Ox._('to {0} list.', [ui._list == ':' ? 'a' : 'another'])
: Ox._('to your library or to one of your lists.')
);
}
return $('<div>')
.append(
$('<div>')
.css({
float: 'left',
width: '16px',
height: '16px',
padding: '1px',
border: '3px solid rgb(' + Ox.Theme.getThemeData().symbolDefaultColor.join(', ') + ')',
borderRadius: '12px',
margin: '3px 2px 2px 2px'
})
.append(
$('<img>')
.attr({src: Ox.UI.getImageURL(image)})
.css({width: '16px', height: '16px'})
)
)
.append(
$('<div>')
.css({
float: 'left',
margin: '1px 2px 2px 2px',
fontSize: '11px',
whiteSpace: 'nowrap'
})
.html(text)
);
}
function isAtListsTop(e) {
return ui.showSidebar
&& e.clientX < ui.sidebarSize
&& e.clientY >= 44 && e.clientY < 60;
}
function isAtListsBottom(e) {
var listsBottom = window.innerHeight - oml.getInfoHeight();
return ui.showSidebar
&& e.clientX < ui.sidebarSize
&& e.clientY >= listsBottom - 16 && e.clientY < listsBottom;
}
function keydown(e) {
if (e.metaKey) {
drag.action = 'move';
$tooltip.options({title: getTitle()}).show();
}
}
function keyup(e) {
if (drag.action == 'move') {
drag.action = 'copy';
$tooltip.options({title: getTitle()}).show();
}
}
};
2016-01-14 09:25:14 +00:00
oml.formatAuthor = function(author) {
var isEditor = false;
return (author || []).map(function(value) {
if (Ox.endsWith(value, ' (Ed.)')) {
isEditor = true;
value = value.slice(0, -6);
}
return value;
}).join(', ') + (isEditor ? ' (Ed.)' : '');
};
2014-05-14 09:57:11 +00:00
oml.getEditTooltip = function(title) {
return function(e) {
var $target = $(e.target);
return (
$target.is('a') || $target.parents('a').length
? Ox._('Shift+doubleclick to edit') : Ox._('Doubleclick to edit')
) + (title ? ' ' + Ox._(title) : '');
}
};
2014-05-04 17:26:43 +00:00
(function() {
// Note: getFindState has to run after getListState and getFilterState
function everyCondition(conditions, key, operator) {
// If every condition has the given key and operator
// (excluding conditions where all subconditions match)
// returns true, otherwise false
return Ox.every(conditions, function(condition) {
return condition.key == key && condition.operator == operator;
});
}
function oneCondition(conditions, key, operator, includeSubconditions) {
// If exactly one condition has the given key and operator
// (including or excluding conditions where all subconditions match)
// returns the corresponding index, otherwise returns -1
var indices = Ox.indicesOf(conditions, function(condition) {
return (
condition.conditions
? includeSubconditions && everyCondition(condition.conditions, key, operator)
: condition.key == key && condition.operator == operator
);
});
return indices.length == 1 ? indices[0] : -1;
}
oml.getFindState = function(find) {
// The find element is populated if exactly one condition in an & query
// has a findKey as key and "=" as operator (and all other conditions
// are either list or filters), or if all conditions in an | query have
// the same filter id as key and "==" as operator
Ox.Log('Find', 'getFindState', find)
// FIXME: this is still incorrect when you select a lot of filter items
// and reload the page (will be advanced)
var conditions,
indices,
state = {index: -1, key: '*', value: ''},
ui = oml.user.ui;
if (find.operator == '&') {
// number of conditions that are not list or filters
conditions = find.conditions.length
- !!ui._list
- ui._filterState.filter(function(filter) {
return filter.index > -1;
}).length;
// indices of non-advanced find queries
indices = oml.config.findKeys.map(function(findKey) {
return oneCondition(find.conditions, findKey.id, '=');
}).filter(function(index) {
return index > -1;
});
state = conditions == 1 && indices.length == 1 ? {
index: indices[0],
key: find.conditions[indices[0]].key,
value: Ox.decodeURIComponent(find.conditions[indices[0]].value)
} : {
index: -1,
key: conditions == 0 && indices.length == 0 ? '*' : 'advanced',
value: ''
};
} else {
state = {
index: -1,
key: 'advanced',
value: ''
};
Ox.forEach(ui.filters, function(key) {
if (everyCondition(find.conditions, key, '==')) {
state.key = '*';
return false;
}
});
}
return state;
}
oml.getFilterState = function(find) {
// A filter is selected if exactly one condition in an & query or every
// condition in an | query has the filter id as key and "==" as operator
var ui = oml.user.ui;
return ui.filters.map(function(filter) {
// FIXME: cant index be an empty array, instead of -1?
var key = filter.id,
state = {index: -1, find: Ox.clone(find, true), selected: []};
if (find.operator == '&') {
// include conditions where all subconditions match
state.index = oneCondition(find.conditions, key, '==', true);
if (state.index > -1) {
state.selected = find.conditions[state.index].conditions
? find.conditions[state.index].conditions.map(function(condition) {
return condition.value;
})
: [find.conditions[state.index].value];
}
} else {
if (everyCondition(find.conditions, key, '==')) {
state.index = Ox.range(find.conditions.length);
state.selected = find.conditions.map(function(condition) {
return condition.value;
});
}
}
if (state.selected.length) {
if (Ox.isArray(state.index)) {
// every condition in an | query matches this filter
state.find = {conditions: [], operator: ''};
} else {
// one condition in an & query matches this filter
state.find.conditions.splice(state.index, 1);
if (
state.find.conditions.length == 1
&& state.find.conditions[0].conditions
) {
// unwrap single remaining bracketed query
state.find = {
conditions: state.find.conditions[0].conditions,
operator: state.find.conditions[0].operator
};
}
}
}
return state;
});
}
oml.getListState = function(find) {
// A list is selected if exactly one condition in an & query has "list"
// as key and "==" as operator
var index, state = '';
if (find.operator == '&') {
index = oneCondition(find.conditions, 'list', '==');
if (index > -1) {
state = find.conditions[index].value;
}
}
return state;
};
}());
2014-05-21 00:02:39 +00:00
oml.getFilterSizes = function() {
var ui = oml.user.ui;
return Ox.splitInt(
window.innerWidth - ui.showSidebar * ui.sidebarSize - 1,
5
);
};
oml.getIconInfoColor = function(type, data) {
2014-05-12 12:57:47 +00:00
return type == 'extension' ? (
2016-01-16 08:53:44 +00:00
data.extension == 'cbr' ? [[224, 224, 32], [192, 192, 0], [255, 255, 192]]
: data.extension == 'epub' ? [[32, 160, 32], [0, 128, 0], [128, 255, 128]]
2014-05-04 17:26:43 +00:00
: data.extension == 'pdf' ? (
2014-05-12 12:57:47 +00:00
data.textsize
? [[224, 32, 32], [192, 0, 0], [255, 192, 192]]
: [[224, 128, 32], [192, 96, 0], [255, 192, 128]]
2014-05-04 17:26:43 +00:00
)
2014-05-12 12:57:47 +00:00
: data.extension == 'txt' ? [[255, 255, 255], [224, 224, 224], [0, 0, 0]]
: [[96, 96, 96], [64, 64, 64], [192, 192, 192]]
) : data.mediastate == 'available' ? [[32, 160, 32], [0, 128, 0], [128, 255, 128]]
: data.mediastate == 'transferring' ? [[160, 160, 32], [128, 128, 0], [255, 255, 128]]
: [[224, 32, 32], [192, 0, 0], [255, 192, 192]];
2014-05-04 17:26:43 +00:00
};
2014-05-12 12:57:47 +00:00
oml.getInfoHeight = function() {
return Math.min(
oml.user.ui.sidebarSize,
window.innerHeight - 20 - 24 - 16 - 1
);
};
oml.getListData = function(list) {
2014-05-14 09:57:11 +00:00
var ui = oml.user.ui;
list = Ox.isUndefined(list) ? ui._list : list;
return ui._lists ? Ox.getObjectById(ui._lists, list) : {};
2014-05-12 12:57:47 +00:00
};
2014-05-04 17:26:43 +00:00
oml.getListFoldersHeight = function() {
var ui = oml.user.ui;
2014-05-19 15:00:33 +00:00
return oml.$ui.folder.reduce(function(value, $folder, index) {
2014-05-04 17:26:43 +00:00
var items = oml.$ui.folderList[index].options('items').length;
2014-05-19 15:00:33 +00:00
return value + 16 + !$folder.options('collapsed') * (1 + items) * 16;
2014-05-04 17:26:43 +00:00
}, 16);
};
oml.getListFoldersWidth = function() {
var ui = oml.user.ui;
return ui.sidebarSize - (
oml.$ui.appPanel
&& oml.getListFoldersHeight()
2014-05-12 12:57:47 +00:00
> window.innerHeight - 20 - 24 - 1 - ui.showInfo * oml.getInfoHeight()
2014-05-04 17:26:43 +00:00
? Ox.UI.SCROLLBAR_SIZE : 0
);
};
2014-05-18 23:24:04 +00:00
oml.getLists = function(callback) {
var ui = oml.user.ui;
Ox.Request.clearCache('getLists');
oml.api.getLists(function(result) {
ui._lists = result.data.lists.map(function(list) {
// FIXME: 'editable' is notoriously vague
list.name = list.type == 'libraries' ? Ox._('Libraries')
: list.type == 'library' ? Ox._('Library') : list.name;
return Ox.extend(list, {
2014-05-25 14:05:26 +00:00
editable: list.user == '' && list.type == 'static',
2014-05-25 12:16:04 +00:00
own: list.user == '',
2016-01-11 17:59:42 +00:00
title: Ox.encodeHTMLEntities((list.user ? list.user + ': ' : '') + list.name)
2014-05-18 23:24:04 +00:00
});
});
callback(ui._lists);
});
};
oml.getOwnListNames = function() {
2014-10-31 11:46:32 +00:00
var ui = oml.user.ui;
2014-05-18 23:24:04 +00:00
return ui._lists.filter(function(list) {
2014-10-31 11:46:32 +00:00
return list.user == '' && list.type != 'library';
}).map(function(list) {
2014-05-18 23:24:04 +00:00
return list.name;
});
2014-10-31 11:46:32 +00:00
};
2014-05-18 23:24:04 +00:00
2014-05-12 12:57:47 +00:00
oml.getPageTitle = function(stateOrURL) {
var page = Ox.getObjectById(
oml.config.pages,
Ox.isObject(stateOrURL) ? stateOrURL.page : stateOrURL.slice(1)
);
return (page ? page.title + ' – ' : '') + 'Open Media Library';
};
oml.getSortOperator = function(key) {
var itemKey = Ox.getObjectById(oml.config.itemKeys, key);
return itemKey.sortOperator
|| Ox.contains(
['string', 'text'],
Ox.isArray(itemKey.type) ? itemKey.type[0] : itemKey.type
) ? '+' : '-';
};
2014-05-18 23:24:04 +00:00
oml.getUsers = function(callback) {
2014-05-25 18:06:12 +00:00
var ui = oml.user.ui;
Ox.Request.clearCache('getUsers');
oml.api.getUsers(function(result) {
2014-05-27 15:29:10 +00:00
var users = [{
2014-05-12 12:57:47 +00:00
id: oml.user.id,
2014-05-25 12:16:04 +00:00
name: '',
2014-05-12 12:57:47 +00:00
online: oml.user.online
2014-05-25 18:06:12 +00:00
}].concat(
Ox.sortBy(result.data.users.filter(function(user) {
2014-05-12 12:57:47 +00:00
return user.peered;
2014-05-25 18:06:12 +00:00
}), 'index')
2014-05-12 12:57:47 +00:00
);
2014-05-25 12:16:04 +00:00
ui._users = users;
callback(users);
});
2014-05-12 12:57:47 +00:00
};
2014-05-18 23:24:04 +00:00
oml.getValidName = function(value, names, chars) {
var index = 1, length = 256, suffix;
if (chars) {
value = value.replace(
new RegExp('[' + Ox.escapeRegExp(chars) + ']', 'g'),
''
);
}
value = Ox.clean(Ox.clean(value).slice(0, length));
names = names || [];
while (Ox.contains(names, value)) {
suffix = ' [' + (++index) + ']';
value = value.replace(/ \[\d+\]$/, '')
.slice(0, length - suffix.length) + suffix;
};
return value;
};
2014-05-04 17:26:43 +00:00
oml.hasDialogOrScreen = function() {
return !!$('.OxDialog:visible').length
|| !!$('.OxFullscreen').length
|| !!$('.OxScreen').length;
};
2014-05-19 18:12:02 +00:00
oml.openLink = function(url) {
if (Ox.startsWith(url, 'mailto:')) {
window.open(url);
} else {
2014-05-21 00:02:39 +00:00
window.open('/url=' + encodeURIComponent(url), '_blank');
2014-05-19 18:12:02 +00:00
}
};
2016-01-12 08:52:20 +00:00
oml.reloadLists = function() {
Ox.Request.clearCache('find');
2016-01-16 08:57:38 +00:00
if (oml.user.ui.showFilters) {
oml.$ui.filters.forEach(function($filter) {
$filter.reloadList(true);
});
}
2016-01-12 08:52:20 +00:00
oml.$ui.list.reloadList(true);
2016-01-16 08:57:38 +00:00
oml.$ui.browser.reloadList(true);
2014-05-12 12:57:47 +00:00
};
2014-05-25 14:05:26 +00:00
oml.renameUser = function(data) {
2014-05-25 18:06:12 +00:00
2014-05-25 14:05:26 +00:00
var ui = oml.user.ui,
index = Ox.getIndexById(ui._users, data.id),
2015-12-02 21:05:23 +00:00
name,
2014-05-25 18:06:12 +00:00
set = {},
2015-12-02 21:05:23 +00:00
oldFind,
newFind;
if (index == -1) {
return;
}
2014-05-25 18:06:12 +00:00
2015-12-02 21:05:23 +00:00
name = ui._users[index].name;
oldFind = Ox.clone(ui.find, true);
newFind = Ox.clone(ui.find, true);
2014-05-25 14:05:26 +00:00
ui._users[index].name = data.name;
ui._users[index].nickname = data.nickname;
2016-01-05 15:13:42 +00:00
set['showFolder.' + oml.UI.encode(name)] = null;
set['showFolder.' + oml.UI.encode(data.name)] = ui.showFolder[name];
2014-05-25 14:05:26 +00:00
Ox.forEach(ui.lists, function(value, key) {
var split = key.split(':'),
username = split[0],
listname = split.slice(1).join(':');
if (username == name) {
2016-01-05 15:13:42 +00:00
set['lists.' + oml.UI.encode(key)] = null;
set['lists.' + oml.UI.encode(data.name + ':' + listname)] = value;
2014-05-25 14:05:26 +00:00
}
});
2014-05-25 18:06:12 +00:00
ui._lists.filter(function(list) {
return list.user === '' && list.type == 'smart';
}).forEach(function(list) {
updateConditions(list.query);
});
2014-05-25 14:05:26 +00:00
oml.UI.set(set, false);
2014-05-25 18:06:12 +00:00
updateConditions(newFind);
if (!Ox.isEqual(oldFind, newFind)) {
oml.replaceURL = true;
oml.UI.set({find: newFind}, false);
}
oml.$ui.folders.updateUser(index);
function updateCondition(condition) {
if (condition.key == 'list') {
condition.value = condition.value.replace(
new RegExp('^' + Ox.escapeRegExp(name) + ':'),
data.name + ':'
);
}
}
function updateConditions(query) {
query.conditions.forEach(function(condition) {
if (!condition.conditions) {
updateCondition(condition);
} else {
condition.conditions.forEach(updateCondition);
}
});
}
2014-05-25 14:05:26 +00:00
};
2014-05-04 17:26:43 +00:00
oml.resizeFilters = function() {
// ...
};
oml.resizeListFolders = function() {
// FIXME: does this have to be here?
var width = oml.getListFoldersWidth(),
2015-04-20 07:50:42 +00:00
columnWidth = width - 16 - 48;
2014-05-04 17:26:43 +00:00
oml.$ui.librariesList
2014-05-17 11:45:57 +00:00
.css({width: width + 'px'})
.resizeColumn('name', columnWidth);
2014-05-04 17:26:43 +00:00
Ox.forEach(oml.$ui.folder, function($folder, index) {
$folder.css({width: width + 'px'});
oml.$ui.libraryList[index]
2014-05-17 11:45:57 +00:00
.css({width: width + 'px'})
.resizeColumn('name', columnWidth);
2014-05-04 17:26:43 +00:00
oml.$ui.folderList[index]
2014-05-17 11:45:57 +00:00
.css({width: width + 'px'})
.resizeColumn('name', columnWidth);
2014-05-04 17:26:43 +00:00
});
2014-05-19 15:00:33 +00:00
};
oml.resizeWindow = function() {
oml.$ui.leftPanel && oml.$ui.leftPanel.size(2, oml.getInfoHeight());
oml.resizeListFolders();
2016-01-12 13:41:52 +00:00
oml.$ui.viewPanel && oml.$ui.viewPanel.updateElement();
2014-05-19 18:12:02 +00:00
oml.$ui.list && oml.$ui.list.size();
2014-05-04 17:26:43 +00:00
};
oml.updateFilterMenus = function() {
// FIXME: does this have to be a utils function?
var selected = oml.$ui.filters.map(function($filter) {
return !Ox.isEmpty($filter.options('selected'));
}),
filtersHaveSelection = !!Ox.sum(selected);
oml.$ui.filters.forEach(function($filter, index) {
$filter[
selected[index] ? 'enableMenuItem' : 'disableMenuItem'
]('clearFilter');
$filter[
filtersHaveSelection ? 'enableMenuItem' : 'disableMenuItem'
]('clearFilters');
});
};
oml.validatePublicKey = function(value) {
return /^[a-z0-9+\/]{16}$/.test(value);
2014-05-04 17:26:43 +00:00
};
2015-05-14 11:40:29 +00:00
oml.updateDebugMenu = function() {
var menu = $('.OxTitle').filter(function(i, e) {
return e.innerHTML == 'Debug'
});
oml.user.ui.showDebugMenu ? menu.show() : menu.hide();
};
2015-06-06 17:54:44 +00:00
oml.supportedExtensions = ['pdf', 'epub', 'kepub', 'cbr', 'cbz'];
2016-01-13 16:17:51 +00:00
oml.upload = function(fileslist, callback) {
var files = [], ids = [];
for (var i = 0; i < fileslist.length; i++) {
var extension = Ox.last(fileslist[i].name.split('.'));
2015-06-06 17:54:44 +00:00
if (Ox.contains(oml.supportedExtensions, extension)) {
2016-01-13 16:17:51 +00:00
files.push(fileslist[i]);
2015-06-06 17:54:44 +00:00
}
}
2016-01-13 16:17:51 +00:00
Ox.serialForEach(files, function(file, index, array, next) {
var request = new XMLHttpRequest(),
url = '/api/upload/';
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200) {
next();
var response = JSON.parse(request.responseText);
ids.concat(response.data.ids);
} else {
callback(null, {
code: request.status,
text: request.statusText
});
}
}
};
var formData = new FormData();
formData.append('files', file);
if (oml.user.ui._list[0] == ':' && oml.user.ui._list.length > 1) {
formData.append('list', oml.user.ui._list.slice(1));
}
request.open('post', url, true);
request.send(formData);
}, function() {
callback({
'status': {'code': 200},
'data': {'ids': ids}
});
});
2015-06-06 17:54:44 +00:00
};