and more...

This commit is contained in:
j 2014-05-13 01:43:27 +02:00
parent 10d2f35b7b
commit 0c18dad1b5
20 changed files with 293 additions and 146 deletions

2
ctl
View file

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
HOST="127.0.0.1:9842" HOST="[::1]:9842"
NAME="openmedialibrary" NAME="openmedialibrary"
PID="/tmp/$NAME.pid" PID="/tmp/$NAME.pid"

View file

@ -188,7 +188,7 @@ class Changelog(db.Model):
l.add_items(ids) l.add_items(ids)
return True return True
def action_removelistitem(self, user, timestamp, name, ids): def action_removelistitems(self, user, timestamp, name, ids):
from user.models import List from user.models import List
l = List.get(user.id, name) l = List.get(user.id, name)
if l: if l:
@ -205,7 +205,7 @@ class Changelog(db.Model):
user.save() user.save()
return True return True
def action_adduser(self, user, timestamp, peerid, username): def action_addpeer(self, user, timestamp, peerid, username):
from user.models import User from user.models import User
if not 'users' in user.info: if not 'users' in user.info:
user.info['users'] = {} user.info['users'] = {}
@ -215,7 +215,7 @@ class Changelog(db.Model):
#fixme, add username to user? #fixme, add username to user?
return True return True
def action_removeuser(self, user, timestamp, peerid): def action_removepeer(self, user, timestamp, peerid):
if 'users' in user.info and peerid in user.info['users']: if 'users' in user.info and peerid in user.info['users']:
del user.info['users'][peerid] del user.info['users'][peerid]
user.save() user.save()

View file

@ -172,11 +172,7 @@ def download(request):
data = json.loads(request.form['data']) if 'data' in request.form else {} data = json.loads(request.form['data']) if 'data' in request.form else {}
item = models.Item.get(data['id']) item = models.Item.get(data['id'])
if item: if item:
item.transferprogress = 0 item.queue_download()
item.transferadded = datetime.now()
p = models.User.get(settings.USER_ID)
if p not in item.users:
item.users.append(p)
item.update() item.update()
response = {'status': 'queued'} response = {'status': 'queued'}
return response return response
@ -190,9 +186,11 @@ def cancelDownload(request):
if item: if item:
item.transferprogress = None item.transferprogress = None
item.transferadded = None item.transferadded = None
p = models.User.get(settings.USER_ID) p = state.user()
if p in item.users: if p in item.users:
item.users.remove(p) item.users.remove(p)
for l in item.lists.filter_by(user_id=settings.USER_ID):
l.remove(item)
item.update() item.update()
response = {'status': 'cancelled'} response = {'status': 'cancelled'}
return response return response

View file

@ -22,6 +22,7 @@ from person import get_sort_name
import media import media
from meta import scraper from meta import scraper
import state
import utils import utils
from oxflask.db import MutableDict from oxflask.db import MutableDict
@ -204,8 +205,8 @@ class Item(db.Model):
if key.get('find') or key.get('filter'): if key.get('find') or key.get('filter'):
value = self.json().get(key['id'], None) value = self.json().get(key['id'], None)
if key.get('filterMap') and value: if key.get('filterMap') and value:
value = re.compile(key.get('filterMap')).findall(value)[0] value = re.compile(key.get('filterMap')).findall(value)
print key['id'], value if value: value = value[0]
if value: if value:
if isinstance(value, list): if isinstance(value, list):
Find.query.filter_by(item_id=self.id, key=key['id']).delete() Find.query.filter_by(item_id=self.id, key=key['id']).delete()
@ -326,9 +327,20 @@ class Item(db.Model):
print 'FIX UPDATE', mainid print 'FIX UPDATE', mainid
self.update() self.update()
def queue_download(self):
u = state.user()
if not u in self.users:
self.transferprogress = 0
self.transferadded = datetime.now()
self.users.append(u)
def save_file(self, content): def save_file(self, content):
p = User.get(settings.USER_ID) u = state.user()
f = File.get(self.id) f = File.get(self.id)
content_id = media.get_id(data=content)
if content_id != self.id:
print 'INVALID CONTENT', self.id, 'vs', content_id
return False
if not f: if not f:
path = 'Downloads/%s.%s' % (self.id, self.info['extension']) path = 'Downloads/%s.%s' % (self.id, self.info['extension'])
f = File.get_or_create(self.id, self.info, path=path) f = File.get_or_create(self.id, self.info, path=path)
@ -337,11 +349,11 @@ class Item(db.Model):
ox.makedirs(os.path.dirname(path)) ox.makedirs(os.path.dirname(path))
with open(path, 'wb') as fd: with open(path, 'wb') as fd:
fd.write(content) fd.write(content)
if p not in self.users: if u not in self.users:
self.users.append(p) self.users.append(u)
self.transferprogress = 1 self.transferprogress = 1
self.added = datetime.now() self.added = datetime.now()
Changelog.record(p, 'additem', self.id, self.info) Changelog.record(u, 'additem', self.id, self.info)
self.update() self.update()
trigger_event('transfer', { trigger_event('transfer', {
'id': self.id, 'progress': 1 'id': self.id, 'progress': 1

View file

@ -27,7 +27,7 @@ class LocalNodes(Thread):
_BROADCAST = "ff02::1" _BROADCAST = "ff02::1"
_PORT = 9851 _PORT = 9851
TTL = 2 TTL = 1
def __init__(self, app): def __init__(self, app):
self._app = app self._app = app

View file

@ -1,12 +1,23 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from __future__ import division
import base64
import hashlib
import os
import ox
import pdf import pdf
import epub import epub
import txt import txt
import os
import base64
import ox
def get_id(f): def get_id(f=None, data=None):
return base64.b32encode(ox.sha1sum(f).decode('hex')) if data:
return base64.b32encode(hashlib.sha1(data).digest())
else:
return base64.b32encode(ox.sha1sum(f).decode('hex'))
def metadata(f): def metadata(f):
ext = f.split('.')[-1] ext = f.split('.')[-1]

View file

@ -79,9 +79,18 @@ def api_rejectPeering(app, user_id, message):
def api_removePeering(app, user_id, message): def api_removePeering(app, user_id, message):
user = User.get(user_id) user = User.get(user_id)
if user: if user:
user.peered = False
user.info['message'] = message user.info['message'] = message
user.save() user.update_peering(False)
trigger_event('peering', {'id': user.id, 'peered': user.peered}) trigger_event('peering', user.json())
return True
return False
def api_cancelPeering(app, user_id, message):
user = User.get(user_id)
if user:
user.info['message'] = message
user.update_peering(False)
trigger_event('peering', user.json())
user.peered = False
return True return True
return False return False

View file

@ -169,12 +169,22 @@ class Node(object):
r = self.request('rejectPeering', message) r = self.request('rejectPeering', message)
p = self.user p = self.user
p.update_peering(False) p.update_peering(False)
self.go_online()
return True return True
def removePeering(self, message): def removePeering(self, message):
print 'remove peering!!!', self.user
r = self.request('removePeering', message) r = self.request('removePeering', message)
p = self.user p = self.user
p.update_peering(False) p.update_peering(False)
self.go_online()
return True
def cancelPeering(self, message):
r = self.request('cancelPeering', message)
p = self.user
p.update_peering(False)
self.go_online()
return True return True
def download(self, item): def download(self, item):

View file

@ -210,3 +210,12 @@ def removePeering(request):
state.nodes.queue(p.id, 'removePeering', data.get('message', '')) state.nodes.queue(p.id, 'removePeering', data.get('message', ''))
return {} return {}
actions.register(removePeering, cache=False) actions.register(removePeering, cache=False)
@returns_json
def cancelPeering(request):
data = json.loads(request.form['data']) if 'data' in request.form else {}
p = models.User.get_or_create(data['id'])
state.nodes.queue('add', p.id)
state.nodes.queue(p.id, 'cancelPeering', data.get('message', ''))
return {}
actions.register(cancelPeering, cache=False)

View file

@ -72,9 +72,11 @@ class User(db.Model):
self.info['username'] = username self.info['username'] = username
self.set_nickname(self.info.get('username', 'anonymous')) self.set_nickname(self.info.get('username', 'anonymous'))
Changelog.record(state.user(), 'addpeer', self.id, self.nickname)
else: else:
self.peered = False self.peered = False
self.nickname = None self.nickname = None
self.save()
for i in self.items: for i in self.items:
i.users.remove(self) i.users.remove(self)
if not i.users: if not i.users:
@ -82,6 +84,8 @@ class User(db.Model):
db.session.delete(i) db.session.delete(i)
else: else:
i.update_lists() i.update_lists()
Changelog.query.filter_by(user_id=self.id).delete()
Changelog.record(state.user(), 'removepeer', self.id)
self.save() self.save()
def set_nickname(self, nickname): def set_nickname(self, nickname):
@ -159,6 +163,7 @@ class List(db.Model):
for item_id in items: for item_id in items:
i = Item.get(item_id) i = Item.get(item_id)
self.items.append(i) self.items.append(i)
i.queue_download()
i.update() i.update()
db.session.add(self) db.session.add(self)
db.session.commit() db.session.commit()

View file

@ -7,7 +7,7 @@ oml.ui.backButton = function() {
that = Ox.Button({ that = Ox.Button({
style: 'squared', style: 'squared',
title: 'arrowLeft', title: 'arrowLeft',
tooltip: Ox._('Back to Books'), tooltip: Ox._('Back to Books {0}', [Ox.UI.symbols.control + 'W']),
type: 'image' type: 'image'
}) })
.css({ .css({

View file

@ -0,0 +1,38 @@
'use strict';
oml.ui.deleteListDialog = function() {
var ui = oml.user.ui,
that = oml.ui.confirmDialog({
buttons: [
Ox.Button({
title: Ox._('No, Keep List')
}),
Ox.Button({
title: Ox._('Yes, Delete List')
})
],
content: Ox._('Are you sure you want to delete this list?'),
title: Ox._('Delete List')
}, function() {
oml.api.removeList({
id: ui._list
}, function() {
oml.UI.set({
find: {
conditions: [{
key: 'list',
operator: '==',
value: ':'
}],
operator: '&'
}
});
oml.updateLists();
});
});
return that;
};

View file

@ -37,11 +37,11 @@ oml.ui.findElement = function() {
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
if (data.value == 'advanced') { if (data.value == 'advanced') {
oml.$ui.mainMenu.checkItem('findMenu_find_' + previousFindKey);
that.updateElement(); that.updateElement();
//oml.$ui.mainMenu.checkItem('findMenu_find_' + previousFindKey);
oml.$ui.filterDialog = oml.ui.filterDialog().open(); oml.$ui.filterDialog = oml.ui.filterDialog().open();
} else { } else {
//oml.$ui.mainMenu.checkItem('findMenu_find_' + data.value); oml.$ui.mainMenu.checkItem('findMenu_find_' + data.value);
oml.$ui.findInput.options({ oml.$ui.findInput.options({
autocomplete: getAutocomplete(), autocomplete: getAutocomplete(),
placeholder: '' placeholder: ''

View file

@ -77,7 +77,7 @@ oml.ui.folders = function() {
collapsed: false, collapsed: false,
extras: [ extras: [
oml.ui.statusIcon( oml.ui.statusIcon(
!oml.user.online ? 'unknown' !oml.user.online && index ? 'unknown'
: user.online ? 'connected' : user.online ? 'connected'
: 'disconnected' : 'disconnected'
), ),
@ -179,14 +179,14 @@ oml.ui.folders = function() {
oml.$ui.folderList[index] = oml.ui.folderList({ oml.$ui.folderList[index] = oml.ui.folderList({
draggable: !!index, draggable: !!index,
items: items, items: items,
sortable: true sortable: !index
}) })
.bindEvent({ .bindEvent({
add: function() { add: function() {
!index && oml.addList(); !index && oml.addList();
}, },
'delete': function() { 'delete': function() {
!index && oml.deleteList(); !index && oml.ui.deleteListDialog().open();
}, },
key_control_d: function() { key_control_d: function() {
oml.addList(ui._list); oml.addList(ui._list);
@ -224,11 +224,6 @@ oml.ui.folders = function() {
oml.UI.set({find: getFind(libraryId)}); oml.UI.set({find: getFind(libraryId)});
} }
}) })
.bindEvent(function(data, event) {
if (!index) {
Ox.print('LIST EVENT', event, data);
}
})
.css({height: items.length * 16 + 'px'}) .css({height: items.length * 16 + 'px'})
.appendTo($content) .appendTo($content)
); );

View file

@ -20,9 +20,6 @@ oml.ui.gridView = function() {
? (data.author || '') : data[sortKey] ? (data.author || '') : data[sortKey]
); );
size = size || 128; size = size || 128;
Ox.print('WTF', '-webkit-linear-gradient(top, ' + color.slice(2).map(function(rgba) {
return 'rgba(' + rgba.join(', ') + ')';
}).join(', ') + ')');
return { return {
extra: ui.showFileInfo ? $('<div>') extra: ui.showFileInfo ? $('<div>')
.css({ .css({

View file

@ -395,52 +395,56 @@ oml.ui.infoView = function() {
} }
}); });
Ox.Button({ if (data.mediastate == 'available') {
title: Ox._('Identify Book...'),
width: 128
})
.css({marginTop: '16px'})
.bindEvent({
click: function() {
identify(data);
}
})
.appendTo($data);
[ Ox.Button({
'isbn10', 'isbn13', 'lccn', 'olid', 'oclc', 'mainid' title: Ox._('Identify Book...'),
].forEach(function(id, index) { width: 128
var title = Ox.getObjectById(oml.config.itemKeys, id).title,
placeholder = id == 'mainid' ? 'none' : 'unknown';
$('<div>')
.css({
marginTop: (index == 0 ? 10 : 6) + 'px',
fontWeight: 'bold'
})
.text(title)
.appendTo($data);
Ox.EditableContent({
editable: true,
format: function(value) {
return id == 'mainid'
? Ox.getObjectById(oml.config.itemKeys, value).title
: value;
},
placeholder: placeholder,
tooltip: Ox._('Doubleclick to edit'),
value: data[id] || ''
}) })
.css({marginTop: '16px'})
.bindEvent({ .bindEvent({
submit: function(data) { click: function() {
editMetadata(id, data.value); identify(data);
} }
}) })
.appendTo($data); .appendTo($data);
}); [
'isbn10', 'isbn13', 'lccn', 'olid', 'oclc', 'mainid'
].forEach(function(id, index) {
var title = Ox.getObjectById(oml.config.itemKeys, id).title,
placeholder = id == 'mainid' ? 'none' : 'unknown';
$('<div>')
.css({
marginTop: (index == 0 ? 10 : 6) + 'px',
fontWeight: 'bold'
})
.text(title)
.appendTo($data);
Ox.EditableContent({
editable: true,
format: function(value) {
return id == 'mainid'
? Ox.getObjectById(oml.config.itemKeys, value).title
: value;
},
placeholder: placeholder,
tooltip: Ox._('Doubleclick to edit'),
value: data[id] || ''
})
.bindEvent({
submit: function(data) {
editMetadata(id, data.value);
}
})
.appendTo($data);
});
}
$('<div>').css({height: '16px'}).appendTo($data); $('<div>').css({height: '16px'}).appendTo($data);

View file

@ -53,7 +53,9 @@ oml.ui.listDialog = function() {
}); });
oml.api.getLists(function(result) { oml.api.getLists(function(result) {
var lists = result.data.lists[oml.user.id], var lists = result.data.lists.filter(function(list) {
return list.user == oml.user.preferences.username;
}),
listData = Ox.getObjectById(lists, list), listData = Ox.getObjectById(lists, list),
listNames = lists.map(function(list) { listNames = lists.map(function(list) {
return list.name; return list.name;

View file

@ -4,6 +4,7 @@ oml.ui.mainMenu = function() {
var ui = oml.user.ui, var ui = oml.user.ui,
findState = oml.getFindState(ui.find), findState = oml.getFindState(ui.find),
fromMenu = false,
appItems = Ox.getObjectById(oml.config.pages, 'app').parts, appItems = Ox.getObjectById(oml.config.pages, 'app').parts,
that = Ox.MainMenu({ that = Ox.MainMenu({
@ -227,7 +228,7 @@ oml.ui.mainMenu = function() {
title: Ox._('Find'), title: Ox._('Find'),
items: [ items: [
{ {
id: 'finditems', id: 'find',
title: Ox._('Find'), title: Ox._('Find'),
items: [ items: [
{ {
@ -236,10 +237,12 @@ oml.ui.mainMenu = function() {
min: 1, min: 1,
max: 1, max: 1,
items: oml.config.findKeys.map(function(key) { items: oml.config.findKeys.map(function(key) {
var checked = key.id == findState.key;
return { return {
id: key.id, id: key.id,
checked: key.id == findState.key, title: Ox._(key.title),
title: Ox._(key.title) checked: checked,
keyboard: checked ? 'control f' : ''
}; };
}) })
}, },
@ -332,6 +335,30 @@ oml.ui.mainMenu = function() {
oml.UI.set({page: 'preferences'}); oml.UI.set({page: 'preferences'});
} else if (id == 'users') { } else if (id == 'users') {
oml.UI.set({page: 'users'}); oml.UI.set({page: 'users'});
} else if (id == 'alllibraries') {
if (!ui._list) {
oml.UI.set({item: ''});
} else {
oml.UI.set({find: {
conditions: [],
operator: '&'
}});
}
} else if (id == 'thislibrary') {
if (Ox.endsWith(ui._list, ':')) {
oml.UI.set({item: ''});
} else {
oml.UI.set({find: {
conditions: [{
key: 'list',
operator: '==',
value: ui._list.split(':')[0] + ':'
}],
operator: '&'
}});
}
} else if (id == 'thislist') {
oml.UI.set({item: ''});
} else if (Ox.contains([ } else if (Ox.contains([
'newlist', 'newlistfromselection', 'newlist', 'newlistfromselection',
'newsmartlist', 'newsmartlistfromresults' 'newsmartlist', 'newsmartlistfromresults'
@ -342,7 +369,29 @@ oml.ui.mainMenu = function() {
} else if (id == 'editlist') { } else if (id == 'editlist') {
oml.ui.listDialog.open(); oml.ui.listDialog.open();
} else if (id == 'deletelist') { } else if (id == 'deletelist') {
oml.ui.deleteListDialog.open(); oml.ui.deleteListDialog().open();
} else if (id == 'selectall') {
oml.$ui.list.selectAll();
} else if (id == 'selectnone') {
oml.UI.set({listSelection: []});
} else if (id == 'invertselection') {
oml.$ui.list.invertSelection();
} else if (data.id == 'clearclipboard') {
oml.clipboard.clear();
} else if (data.id == 'delete') {
oml.doHistory('delete', ui.listSelection, ui._list, function() {
oml.UI.set({listSelection: []});
oml.reloadList();
});
} else if (data.id == 'undo') {
fromMenu = true;
oml.undoHistory();
} else if (data.id == 'redo') {
fromMenu = true;
oml.redoHistory();
} else if (id == 'clearhistory') {
fromMenu = true;
oml.history.clear();
} else if (id == 'showsidebar') { } else if (id == 'showsidebar') {
oml.UI.set({showSidebar: !ui.showSidebar}); oml.UI.set({showSidebar: !ui.showSidebar});
} else if (id == 'showinfo') { } else if (id == 'showinfo') {
@ -353,6 +402,13 @@ oml.ui.mainMenu = function() {
oml.UI.set({showBrowser: !ui.showBrowser}); oml.UI.set({showBrowser: !ui.showBrowser});
} else if (id == 'transfers') { } else if (id == 'transfers') {
oml.UI.set({page: 'transfers'}); oml.UI.set({page: 'transfers'});
} else if (id == 'debugmode') {
if (oml.localStorage('enableDebugMode')) {
oml.localStorage['delete']('enableDebugMode');
} else {
oml.localStorage('enableDebugMode', true);
}
window.location.reload();
} else { } else {
Ox.print('MAIN MENU DOES NOT YET HANDLE', id); Ox.print('MAIN MENU DOES NOT YET HANDLE', id);
} }
@ -408,6 +464,12 @@ oml.ui.mainMenu = function() {
oml_listselection: function(data) { oml_listselection: function(data) {
that.replaceMenu('editMenu', getEditMenu()); that.replaceMenu('editMenu', getEditMenu());
}, },
oml_listsort: function(data) {
that.checkItem('sortMenu_sortitems_' + data.value[0].key);
that.checkItem('sortMenu_orderitems_' + (
data.value[0].operator == '+' ? 'ascending' : 'descending')
);
},
oml_showbrowser: function(data) { oml_showbrowser: function(data) {
that.setItemTitle('showbrowser', Ox._((data.value ? 'Hide' : 'Show') + ' Browser')); that.setItemTitle('showbrowser', Ox._((data.value ? 'Hide' : 'Show') + ' Browser'));
}, },
@ -429,7 +491,7 @@ oml.ui.mainMenu = function() {
selectionItems = ui.listSelection.length, selectionItems = ui.listSelection.length,
selectionItemName = ( selectionItemName = (
selectionItems > 1 ? Ox.formatNumber(selectionItems) + ' ' : '' selectionItems > 1 ? Ox.formatNumber(selectionItems) + ' ' : ''
) + Ox._(clipboardItems == 1 ? 'Book' : 'Books'), ) + Ox._(selectionItems == 1 ? 'Book' : 'Books'),
clipboardItems = oml.clipboard.items(), clipboardItems = oml.clipboard.items(),
clipboardType = oml.clipboard.type(), clipboardType = oml.clipboard.type(),
clipboardItemName = !clipboardItems ? '' clipboardItemName = !clipboardItems ? ''
@ -437,11 +499,12 @@ oml.ui.mainMenu = function() {
clipboardItems > 1 ? Ox.formatNumber(clipboardItems) + ' ' : '' clipboardItems > 1 ? Ox.formatNumber(clipboardItems) + ' ' : ''
) + Ox._(clipboardItems == 1 ? 'Book' : 'Books'), ) + Ox._(clipboardItems == 1 ? 'Book' : 'Books'),
canSelect = !ui.item, canSelect = !ui.item,
canDownload = listData.user != username && selectionItems,
canCopy = canSelect && selectionItems, canCopy = canSelect && selectionItems,
canCut = canCopy && listData.editable, canCut = canCopy && listData.editable,
canPaste = listData.editable && clipboardItems, canPaste = listData.editable && clipboardItems,
canAdd = canCopy && clipboardItems && clipboardItemType == ui.section, canAdd = canCopy && clipboardItems && clipboardItemType == ui.section,
canDownload = listData.user != username && selectionItems, canDelete = listData.user == username && selectionItems,
historyItems = oml.history.items(), historyItems = oml.history.items(),
undoText = oml.history.undoText(), undoText = oml.history.undoText(),
redoText = oml.history.redoText(); redoText = oml.history.redoText();
@ -458,13 +521,6 @@ oml.ui.mainMenu = function() {
title: Ox._('Export Books...') title: Ox._('Export Books...')
}, },
{}, {},
{
id: 'download',
title: Ox._('Download {0}', [selectionItemName]),
disabled: !canDownload,
keyboard: 'control d'
},
{},
{ {
id: 'selectall', id: 'selectall',
title: Ox._('Select All'), title: Ox._('Select All'),
@ -484,6 +540,12 @@ oml.ui.mainMenu = function() {
keyboard: 'alt control a' keyboard: 'alt control a'
}, },
{}, {},
{
id: 'download',
title: Ox._('Download {0}', [selectionItemName]),
disabled: !canDownload,
keyboard: 'control d'
},
{ {
id: 'cut', id: 'cut',
title: Ox._('Cut {0}', [selectionItemName]), title: Ox._('Cut {0}', [selectionItemName]),
@ -526,6 +588,12 @@ oml.ui.mainMenu = function() {
disabled: !canCut, disabled: !canCut,
keyboard: 'delete' keyboard: 'delete'
}, },
{
id: 'deletefromlibrary',
title: Ox._('Delete {0} from Library...', [selectionItemName]),
disabled: !canDelete,
keyboard: 'shift delete'
},
{}, {},
{ {
id: 'undo', id: 'undo',
@ -548,6 +616,10 @@ oml.ui.mainMenu = function() {
}; };
} }
function getFindMenu() {
return ;
}
function getListMenu() { function getListMenu() {
var isLibraries = !ui._list, var isLibraries = !ui._list,
isLibrary = Ox.endsWith(ui._list, ':'), isLibrary = Ox.endsWith(ui._list, ':'),
@ -556,50 +628,52 @@ oml.ui.mainMenu = function() {
return { return {
id: 'listMenu', id: 'listMenu',
title: Ox._('List'), title: Ox._('List'),
items: [ items: [].concat(!isLibraries || ui.item ? [
{ {
id: 'libraries', id: 'alllibraries',
title: Ox._('All Libraries'), title: Ox._('All Libraries'),
keyboard: 'shift control w' keyboard: 'shift control w'
}, }
] : []).concat(isList || (isLibrary && ui.item) ? [
{ {
id: 'library', id: 'thislibrary',
title: Ox._('This Library'), title: Ox._('This Library'),
disabled: isLibraries,
keyboard: isLibrary ? 'control w' : '' keyboard: isLibrary ? 'control w' : ''
}, }
] : []).concat(isList && ui.item ? [
{ {
id: 'list', id: 'thislist',
title: Ox._('This List'), title: Ox._('This List'),
disabled: isLibrary, keyboard: isList ? 'control w' : ''
keyboard: isLibrary ? '' : 'control w' }
}, ] : []).concat(!isLibraries || ui.item ? [
{}, {},
] : []).concat([
{ {
id: 'newlist', id: 'newlist',
title: Ox._('New List'), title: Ox._('New List...'),
keyboard: 'control n' keyboard: 'control n'
}, },
{ {
id: 'newlistfromselection', id: 'newlistfromselection',
title: Ox._('New List from Selection'), title: Ox._('New List from Selection...'),
keyboard: 'shift control n', keyboard: 'shift control n',
disabled: !ui.listSelection.length disabled: !ui.listSelection.length
}, },
{ {
id: 'newsmartlist', id: 'newsmartlist',
title: Ox._('New Smart List'), title: Ox._('New Smart List...'),
keyboard: 'alt control n' keyboard: 'alt control n'
}, },
{ {
id: 'newsmartlistfromresults', id: 'newsmartlistfromresults',
title: Ox._('New Smart List from Results'), title: Ox._('New Smart List from Results...'),
keyboard: 'shift alt control n' keyboard: 'shift alt control n'
}, },
{}, {},
{ {
id: 'duplicatelist', id: 'duplicatelist',
title: Ox._('Duplicate List'), title: Ox._('Duplicate List...'),
disabled: !isList disabled: !isList
}, },
{ {
@ -614,13 +688,20 @@ oml.ui.mainMenu = function() {
keyboard: 'delete', keyboard: 'delete',
disabled: !isOwnList disabled: !isOwnList
} }
] ])
}; };
} }
that.update = function() { that.update = function(menu) {
return that.updateMenu('listMenu', getListMenu()) (
.updateMenu('editMenu', getEditMenu()); menu ? Ox.makeArray(menu) : ['listMenu', 'editMenu']
).forEach(function(menu) {
that.updateMenu(
menu,
menu == 'listMenu' ? getListMenu() : getEditMenu()
);
});
return that;
}; };
return that; return that;

View file

@ -2,10 +2,13 @@ oml.addList = function() {
// addList(isSmart, isFrom) or addList(list) [=dupicate] // addList(isSmart, isFrom) or addList(list) [=dupicate]
var args = arguments, var args = arguments,
isDuplicate = args.length == 1, isDuplicate = args.length == 1,
isSmart, isFrom, list, listData, data; isSmart, isFrom, list, listData, data,
username = oml.user.preferences.username;
oml.api.getLists(function(result) { oml.api.getLists(function(result) {
var lists = result.data.lists, var lists = result.data.lists,
listNames = lists[oml.user.id].map(function(list) { listNames = lists.filter(function(list) {
return list.user = username;
}).map(function(list) {
return list.name; return list.name;
}), }),
query; query;
@ -104,38 +107,6 @@ oml.clearFilters = function() {
oml.UI.set({find: find}); oml.UI.set({find: find});
}; };
oml.deleteList = function() {
var ui = oml.user.ui;
oml.ui.confirmDialog({
buttons: [
Ox.Button({
title: Ox._('No, Keep List')
}),
Ox.Button({
title: Ox._('Yes, Delete List')
})
],
content: Ox._('Are you sure you want to delete this list?'),
title: Ox._('Delete List')
}, function() {
oml.api.removeList({
id: ui._list
}, function() {
oml.UI.set({
find: {
conditions: [{
key: 'list',
operator: '==',
value: ':'
}],
operator: '&'
}
});
oml.updateLists();
});
});
};
(function() { (function() {
oml.doHistory = function(action, items, targets, callback) { oml.doHistory = function(action, items, targets, callback) {
@ -415,9 +386,11 @@ oml.enableDragAndDrop = function($list, canMove) {
operator: '&' operator: '&'
} }
}, function(result) { }, function(result) {
/* FIXME
oml.$ui.folderList[drag.target.folder].value( oml.$ui.folderList[drag.target.folder].value(
drag.target.id, 'items', result.data.items drag.target.id, 'items', result.data.items
); );
*/
cleanup(250); cleanup(250);
}); });
drag.action == 'move' && oml.reloadList(); drag.action == 'move' && oml.reloadList();
@ -885,7 +858,9 @@ oml.updateLists = function(callback) {
// FIXME: can this go somewhere else? // FIXME: can this go somewhere else?
Ox.Request.clearCache('getLists'); Ox.Request.clearCache('getLists');
oml.api.getLists(function(result) { oml.api.getLists(function(result) {
var items = result.data.lists[oml.user.id]; var items = result.data.lists.filter(function(list) {
return list.user == oml.user.preferences.username;
});
oml.$ui.folderList[0].options({ oml.$ui.folderList[0].options({
items: items items: items
}) })

View file

@ -10,6 +10,7 @@
"columnView.js", "columnView.js",
"confirmDialog.js", "confirmDialog.js",
"connectionButton.js", "connectionButton.js",
"deleteListDialog.js",
"errorDialog.js", "errorDialog.js",
"filter.js", "filter.js",
"filtersInnerPanel.js", "filtersInnerPanel.js",