updateElement

This commit is contained in:
j 2014-05-17 13:45:57 +02:00
parent 706df6cc4b
commit 877e867d03
35 changed files with 516 additions and 314 deletions

1
ctl
View File

@ -85,6 +85,7 @@ if [ "$1" == "update" ]; then
git pull git pull
$0 db upgrade $0 db upgrade
$0 setup $0 setup
$0 update_static > /dev/null
exit exit
fi fi

View File

@ -84,7 +84,7 @@ class Changelog(db.Model):
c.data = data c.data = data
c.sig = sig c.sig = sig
action, args = json.loads(data) action, args = json.loads(data)
print 'apply change', action print 'apply change', action, args
if getattr(c, 'action_' + action)(user, timestamp, *args): if getattr(c, 'action_' + action)(user, timestamp, *args):
print 'change applied' print 'change applied'
db.session.add(c) db.session.add(c)
@ -166,7 +166,8 @@ class Changelog(db.Model):
i = Item.get(itemid) i = Item.get(itemid)
if not i or i.timestamp > timestamp: if not i or i.timestamp > timestamp:
return True return True
i.users.remove(user) if user in i.users:
i.users.remove(user)
if i.users: if i.users:
i.update() i.update()
else: else:

View File

@ -32,6 +32,8 @@ class UpdateStatic(Command):
oxjs = os.path.join(settings.static_path, 'oxjs') oxjs = os.path.join(settings.static_path, 'oxjs')
if not os.path.exists(oxjs): if not os.path.exists(oxjs):
r('git', 'clone', 'https://git.0x2620.org/oxjs.git', oxjs) r('git', 'clone', 'https://git.0x2620.org/oxjs.git', oxjs)
elif os.path.exists(os.path.join(oxjs, '.git')):
os.system('cd "%s" && git pull' % oxjs)
r('python2', os.path.join(oxjs, 'tools', 'build', 'build.py')) r('python2', os.path.join(oxjs, 'tools', 'build', 'build.py'))
r('python2', os.path.join(settings.static_path, 'py', 'build.py')) r('python2', os.path.join(settings.static_path, 'py', 'build.py'))

View File

@ -108,6 +108,15 @@ def edit(request):
return response return response
actions.register(edit, cache=False) actions.register(edit, cache=False)
@returns_json
def remove(request):
data = json.loads(request.form['data']) if 'data' in request.form else {}
print 'remove files', data['ids']
if 'ids' in data and data['ids']:
for i in models.Item.query.filter(models.Item.id.in_(data['ids'])):
i.remove_file()
return {}
actions.register(remove, cache=False)
@returns_json @returns_json
def findMetadata(request): def findMetadata(request):

View File

@ -9,6 +9,7 @@ import json
import hashlib import hashlib
from datetime import datetime from datetime import datetime
from StringIO import StringIO from StringIO import StringIO
import shutil
import Image import Image
import ox import ox
@ -170,9 +171,7 @@ class Item(db.Model):
def get_path(self): def get_path(self):
f = self.files.first() f = self.files.first()
prefs = settings.preferences return f.fullpath() if f else None
prefix = os.path.join(os.path.expanduser(prefs['libraryPath']), 'Books/')
return os.path.join(prefix, f.path) if f else None
def update_sort(self): def update_sort(self):
for key in config['itemKeys']: for key in config['itemKeys']:
@ -366,6 +365,22 @@ class Item(db.Model):
self.update() self.update()
return False return False
def remove_file(self):
for f in self.files.all():
path = f.fullpath()
print path
if os.path.exists(path):
os.unlink(path)
db.session.delete(f)
user = state.user()
self.users.remove(user)
db.session.commit()
if not self.users:
db.session.delete(self)
else:
self.update()
Changelog.record(user, 'removeitem', self.id)
for key in config['itemKeys']: for key in config['itemKeys']:
if key.get('sort'): if key.get('sort'):
sort_type = key.get('sortType', key['type']) sort_type = key.get('sortType', key['type'])
@ -445,3 +460,49 @@ class File(db.Model):
self.sha1 = sha1 self.sha1 = sha1
self.created = datetime.now() self.created = datetime.now()
self.modified = datetime.now() self.modified = datetime.now()
def fullpath(self):
prefs = settings.preferences
prefix = os.path.join(os.path.expanduser(prefs['libraryPath']), 'Books/')
return os.path.join(prefix, self.path)
def move(self):
prefs = settings.preferences
prefix = os.path.join(os.path.expanduser(prefs['libraryPath']), 'Books/')
j = self.item.json()
current_path = self.fullpath()
author = '; '.join([ox.canonical_name(a) for a in j.get('author', [])])
if not author:
author = 'Unknown Author'
title = j.get('title', 'Untitled')
extension = j['extension']
if len(title) > 100:
title = title[:100]
if author.endswith('.'):
author = author[:-1] + '_'
if author.startswith('.'):
author = '_' + author[1:]
filename = '%s.%s' % (title, extension)
print self.sha1, author, filename
new_path = os.path.join(author[0].upper(), author, filename)
if self.path == new_path:
return
h = ''
while os.path.exists(os.path.join(prefix, new_path)):
h = self.sha1[:len(h)+1]
filename = '%s.%s.%s' % (title, h, extension)
new_path = os.path.join(author[0].upper(), author, filename)
if current_path == os.path.join(prefix, new_path):
break
if self.path != new_path:
path = os.path.join(prefix, new_path)
ox.makedirs(os.path.dirname(path))
shutil.move(current_path, path)
self.path = new_path
self.save()
print 'move', current_path, new_path
def save(self):
db.session.add(self)
db.session.commit()

View File

@ -25,21 +25,14 @@ extensions = ['epub', 'pdf', 'txt']
def remove_missing(): def remove_missing():
dirty = False dirty = False
with app.app_context(): with app.app_context():
user = User.get_or_create(settings.USER_ID)
prefs = settings.preferences prefs = settings.preferences
prefix = os.path.join(os.path.expanduser(prefs['libraryPath']), 'Books/') prefix = os.path.join(os.path.expanduser(prefs['libraryPath']), 'Books/')
for f in File.query: for f in File.query:
if not os.path.exists(f.item.get_path()): path = f.item.get_path()
if not os.path.exists(path):
dirty = True dirty = True
print 'file gone', f, f.item.get_path() print 'file gone', f, path
f.item.users.remove(user) f.item.remove_file()
if not f.item.users:
print 'last user, remove'
db.session.delete(f.item)
else:
f.item.update_lists()
Changelog.record(user, 'removeitem', f.item.id)
db.session.delete(f)
if dirty: if dirty:
db.session.commit() db.session.commit()
@ -171,6 +164,7 @@ def run_import(options=None):
item.meta['mainid']: item.meta[item.meta['mainid']] item.meta['mainid']: item.meta[item.meta['mainid']]
}) })
item.scrape() item.scrape()
file.move()
if listname: if listname:
listitems.append(item.id) listitems.append(item.id)
added += 1 added += 1

View File

@ -58,6 +58,7 @@ def api_requestPeering(app, user_id, username, message):
def api_acceptPeering(app, user_id, username, message): def api_acceptPeering(app, user_id, username, message):
user = User.get(user_id) user = User.get(user_id)
print 'incoming acceptPeering event: pending:', user.pending
if user and user.pending == 'sent': if user and user.pending == 'sent':
if not user.info: if not user.info:
user.info = {} user.info = {}

View File

@ -187,7 +187,9 @@ class Node(object):
return True return True
def acceptPeering(self, message): def acceptPeering(self, message):
print 'run acceptPeering', message
r = self.request('acceptPeering', settings.preferences['username'], message) r = self.request('acceptPeering', settings.preferences['username'], message)
print 'result', r
p = self.user p = self.user
p.update_peering(True) p.update_peering(True)
self.go_online() self.go_online()

View File

@ -192,6 +192,7 @@ def acceptPeering(request):
if len(data.get('id', '')) != 43: if len(data.get('id', '')) != 43:
print 'invalid user id' print 'invalid user id'
return {} return {}
print 'acceptPeering...', data
p = models.User.get_or_create(data['id']) p = models.User.get_or_create(data['id'])
state.nodes.queue('add', p.id) state.nodes.queue('add', p.id)
state.nodes.queue(p.id, 'acceptPeering', data.get('message', '')) state.nodes.queue(p.id, 'acceptPeering', data.get('message', ''))

View File

@ -68,17 +68,23 @@ class User(db.Model):
was_peering = self.peered was_peering = self.peered
if peered: if peered:
self.pending = '' self.pending = ''
self.peered = True
if username: if username:
self.info['username'] = username self.info['username'] = username
self.set_nickname(self.info.get('username', 'anonymous')) self.set_nickname(self.info.get('username', 'anonymous'))
# FIXME: need to set peered to False to not trigger changelog event
# before other side receives acceptPeering request
self.peered = False
self.save()
if not was_peering: if not was_peering:
Changelog.record(state.user(), 'addpeer', self.id, self.nickname) Changelog.record(state.user(), 'addpeer', self.id, self.nickname)
self.peered = True
self.save()
else: else:
self.pending = '' self.pending = ''
self.peered = False self.peered = False
self.nickname = None self.nickname = None
self.save()
List.query.filter_by(user_id=self.id).delete() List.query.filter_by(user_id=self.id).delete()
for i in self.items: for i in self.items:
i.users.remove(self) i.users.remove(self)
@ -167,7 +173,8 @@ 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() if self.user_id == settings.USER_ID:
i.queue_download()
i.update() i.update()
db.session.add(self) db.session.add(self)
db.session.commit() db.session.commit()

View File

@ -94,12 +94,12 @@ oml.ui.appDialog = function() {
}, },
'oml_part.app': function() { 'oml_part.app': function() {
if (ui.page == 'app') { if (ui.page == 'app') {
that.update(); that.updateElement();
} }
} }
}); });
that.update = function(section) { that.updateElement = function(section) {
$panel.selectTab(section); $panel.selectTab(section);
}; };

View File

@ -0,0 +1,37 @@
'use strict';
oml.ui.deleteItemsDialog = function() {
var ui = oml.user.ui,
items = ui.listSelection,
itemsName = Ox._(items.length == 1 ? 'Item' : 'Items'),
theseItemsName = items.length == 1
? Ox._('this item')
: Ox._('these {0} items', [Ox.formatNumber(items.length)]),
that = oml.ui.confirmDialog({
buttons: [
Ox.Button({
title: Ox._('No, Keep {0}', [itemsName])
}),
Ox.Button({
title: Ox._('Yes, Delete {0}', [itemsName])
})
],
content: Ox._('Are you sure that you want to permanently delete {0}?', [theseItemsName]),
title: Ox._('Delete {0}', [itemsName])
}, function() {
oml.api.remove({
ids: items
}, function() {
oml.UI.set({listSelection: []});
Ox.Request.clearCache('find');
oml.$ui.folders.updateElement();
oml.$ui.list.updateElement();
});
});
return that;
};

View File

@ -54,7 +54,7 @@ oml.ui.errorDialog = function() {
return that; return that;
}; };
that.update = function(data) { that.updateElement = function(data) {
// 0 (timeout) or 500 (error) // 0 (timeout) or 500 (error)
var error = data.status.code == 0 ? 'a timeout' : 'an error', var error = data.status.code == 0 ? 'a timeout' : 'an error',
title = data.status.code == 0 ? 'Timeout' : 'Error'; title = data.status.code == 0 ? 'Timeout' : 'Error';

View File

@ -88,7 +88,7 @@ oml.ui.filtersOuterPanel = function() {
oml.updateFilterMenus(); oml.updateFilterMenus();
that.update = function() { that.updateElement = function() {
var filterSizes = oml.getFilterSizes(); var filterSizes = oml.getFilterSizes();
that.size(0, filterSizes[0]) that.size(0, filterSizes[0])
.size(2, filterSizes[4]); .size(2, filterSizes[4]);

View File

@ -11,10 +11,10 @@ oml.ui.folderPlaceholder = function(text) {
padding: '1px 4px', padding: '1px 4px',
}); });
that.updateText = function(text) { that.updateElement = function(text) {
return that.html(text); return that.html(text);
}; };
return that.updateText(text); return that.updateElement(text);
}; };

View File

@ -4,9 +4,9 @@ oml.ui.folders = function() {
var ui = oml.user.ui, var ui = oml.user.ui,
userIndex = {}, userIndex,
$lists = [], $lists,
that = Ox.Element() that = Ox.Element()
.css({ .css({
@ -17,219 +17,6 @@ oml.ui.folders = function() {
oml_find: selectList oml_find: selectList
}); });
$lists.push(
oml.$ui.librariesList = oml.ui.folderList({
items: [
{
id: '',
name: Ox._('All Libraries'),
type: 'libraries',
items: -1
}
]
})
.bindEvent({
load: function() {
oml.api.find({query: getFind()}, function(result) {
oml.$ui.librariesList.value('', 'items', result.data.items);
});
},
select: function() {
oml.UI.set({find: getFind('')});
oml.$ui.librariesList.options({selected: ['']});
},
selectnext: function() {
oml.UI.set(Ox.extend(
{find: getFind(':')},
'showFolder.' + oml.user.preferences.username,
true
));
},
})
.css({height: '16px'})
.appendTo(that)
);
oml.$ui.librariesList.$body.css({height: '16px'}); // FIXME!
oml.$ui.folder = [];
oml.$ui.libraryList = [];
oml.$ui.folderList = [];
oml.getUsersAndLists(function(users, lists) {
Ox.print('GOT USERS AND LISTS', users, lists);
users.forEach(function(user, index) {
var $content,
items = lists.filter(function(list) {
return list.user == user.nickname
&& list.type != 'library';
}),
libraryId = (!index ? '' : user.nickname) + ':'
userIndex[user.nickname] = index;
oml.$ui.folder[index] = Ox.CollapsePanel({
collapsed: false,
extras: [
oml.ui.statusIcon(
!oml.user.online && index ? 'unknown'
: user.online ? 'connected'
: 'disconnected'
),
{},
Ox.Button({
style: 'symbol',
title: 'info',
tooltip: Ox._(!index ? 'Preferences' : 'Profile'),
type: 'image'
})
.bindEvent({
click: function() {
if (!index) {
oml.UI.set({
page: 'preferences',
'part.preferences': 'account'
});
} else {
oml.UI.set({page: 'users'})
}
}
})
],
title: Ox.encodeHTMLEntities(user.nickname)
})
.css({
width: ui.sidebarSize
})
.bindEvent({
toggle: function(data) {
oml.UI.set('showFolder.' + user.nickname, !data.collapsed);
}
})
.bindEvent(
'oml_showfolder.' + user.nickname.toLowerCase(),
function(data) {
oml.$ui.folder[index].options({collapsed: !data.value});
}
)
.appendTo(that);
$content = oml.$ui.folder[index].$content
.css({
height: (1 + items.length) * 16 + 'px'
});
$lists.push(
oml.$ui.libraryList[index] = oml.ui.folderList({
items: [
{
id: libraryId,
name: Ox._('Library'),
type: 'library',
items: -1
}
]
})
.bindEvent({
add: function() {
!index && oml.addList();
},
load: function() {
oml.api.find({
query: getFind(libraryId)
}, function(result) {
oml.$ui.libraryList[index].value(
libraryId, 'items', result.data.items
);
});
},
select: function(data) {
oml.UI.set({find: getFind(data.ids[0])});
},
selectnext: function() {
oml.UI.set({find: getFind(lists[user.id][0].id)});
},
selectprevious: function() {
var userId = !index ? null : users[index - 1].id,
set = {
find: getFind(
!index
? ''
: Ox.last(lists[userId]).id
)
};
if (userId) {
Ox.extend(set, 'showFolder.' + userId, true);
}
oml.UI.set(set);
}
})
.appendTo($content)
);
$lists.push(
oml.$ui.folderList[index] = oml.ui.folderList({
draggable: !!index,
items: items,
sortable: !index
})
.bindEvent({
add: function() {
!index && oml.addList();
},
'delete': function() {
!index && oml.ui.deleteListDialog().open();
},
key_control_d: function() {
oml.addList(ui._list);
},
load: function() {
// ...
},
move: function(data) {
lists[user.id] = data.ids.map(function(listId) {
return Ox.getObjectById(lists[user.id], listId);
});
oml.api.sortLists({
ids: data.ids,
user: user.id
}, function(result) {
// ...
});
},
open: function() {
!index && oml.ui.listDialog().open();
},
select: function(data) {
oml.UI.set({find: getFind(data.ids[0])});
},
selectnext: function() {
if (index < users.length - 1) {
oml.UI.set(Ox.extend(
{find: getFind(users[index + 1].nickname + ':')},
'showFolder.' + users[index + 1].nickname,
true
));
}
},
selectprevious: function() {
oml.UI.set({find: getFind(libraryId)});
}
})
.css({height: items.length * 16 + 'px'})
.appendTo($content)
);
oml.$ui.folderList[index].$body.css({top: '16px'});
});
selectList();
});
function getFind(list) { function getFind(list) {
return { return {
conditions: list ? [{ conditions: list ? [{
@ -257,6 +44,230 @@ oml.ui.folders = function() {
}); });
} }
return that; that.updateElement = function() {
that.empty();
$lists = [];
$lists.push(
oml.$ui.librariesList = oml.ui.folderList({
items: [
{
id: '',
name: Ox._('All Libraries'),
type: 'libraries',
items: -1
}
]
})
.bindEvent({
load: function() {
oml.api.find({query: getFind()}, function(result) {
oml.$ui.librariesList.value('', 'items', result.data.items);
});
},
select: function() {
oml.UI.set({find: getFind('')});
oml.$ui.librariesList.options({selected: ['']});
},
selectnext: function() {
oml.UI.set(Ox.extend(
{find: getFind(':')},
'showFolder.' + oml.user.preferences.username,
true
));
},
})
.css({height: '16px'})
.appendTo(that)
);
oml.$ui.librariesList.$body.css({height: '16px'}); // FIXME!
oml.$ui.folder = [];
oml.$ui.libraryList = [];
oml.$ui.folderList = [];
oml.getUsersAndLists(function(users, lists) {
Ox.print('GOT USERS AND LISTS', users, lists);
userIndex = {};
users.forEach(function(user, index) {
var $content,
items = lists.filter(function(list) {
return list.user == user.nickname
&& list.type != 'library';
}),
libraryId = (!index ? '' : user.nickname) + ':'
userIndex[user.nickname] = index;
oml.$ui.folder[index] = Ox.CollapsePanel({
collapsed: false,
extras: [
oml.ui.statusIcon(
!oml.user.online && index ? 'unknown'
: user.online ? 'connected'
: 'disconnected'
),
{},
Ox.Button({
style: 'symbol',
title: 'info',
tooltip: Ox._(!index ? 'Preferences' : 'Profile'),
type: 'image'
})
.bindEvent({
click: function() {
if (!index) {
oml.UI.set({
page: 'preferences',
'part.preferences': 'account'
});
} else {
oml.UI.set({page: 'users'})
}
}
})
],
title: Ox.encodeHTMLEntities(user.nickname)
})
.css({
width: ui.sidebarSize
})
.bindEvent({
toggle: function(data) {
oml.UI.set('showFolder.' + user.nickname, !data.collapsed);
}
})
.bindEvent(
'oml_showfolder.' + user.nickname.toLowerCase(),
function(data) {
oml.$ui.folder[index].options({collapsed: !data.value});
}
)
.appendTo(that);
$content = oml.$ui.folder[index].$content
.css({
height: (1 + items.length) * 16 + 'px'
});
$lists.push(
oml.$ui.libraryList[index] = oml.ui.folderList({
items: [
{
id: libraryId,
name: Ox._('Library'),
type: 'library',
items: -1
}
]
})
.bindEvent({
add: function() {
!index && oml.addList();
},
load: function() {
oml.api.find({
query: getFind(libraryId)
}, function(result) {
oml.$ui.libraryList[index].value(
libraryId, 'items', result.data.items
);
});
},
select: function(data) {
oml.UI.set({find: getFind(data.ids[0])});
},
selectnext: function() {
oml.UI.set({find: getFind(items[0].id)});
},
selectprevious: function() {
var userId = !index ? null : users[index - 1].id,
set = {
find: getFind(
!index
? ''
: Ox.last(lists[userId]).id
)
};
if (userId) {
Ox.extend(set, 'showFolder.' + userId, true);
}
oml.UI.set(set);
}
})
.appendTo($content)
);
$lists.push(
oml.$ui.folderList[index] = oml.ui.folderList({
draggable: !!index,
items: items,
sortable: !index
})
.bindEvent({
add: function() {
!index && oml.addList();
},
'delete': function() {
!index && oml.ui.deleteListDialog().open();
},
key_control_d: function() {
oml.addList(ui._list);
},
load: function() {
// ...
},
move: function(data) {
lists[user.id] = data.ids.map(function(listId) {
return Ox.getObjectById(items, listId);
});
oml.api.sortLists({
ids: data.ids,
user: user.id
}, function(result) {
// ...
});
},
open: function() {
!index && oml.ui.listDialog().open();
},
select: function(data) {
oml.UI.set({find: getFind(data.ids[0])});
},
selectnext: function() {
if (index < users.length - 1) {
oml.UI.set(Ox.extend(
{find: getFind(users[index + 1].nickname + ':')},
'showFolder.' + users[index + 1].nickname,
true
));
}
},
selectprevious: function() {
oml.UI.set({find: getFind(libraryId)});
}
})
.css({height: items.length * 16 + 'px'})
.appendTo($content)
);
oml.$ui.folderList[index].$body.css({top: '16px'});
});
selectList();
});
return that;
};
return that.updateElement();
}; };

View File

@ -19,16 +19,16 @@ oml.ui.fullscreenButton = function() {
Ox.Fullscreen.enter(oml.$ui.viewer.find('iframe')[0]); Ox.Fullscreen.enter(oml.$ui.viewer.find('iframe')[0]);
}, },
oml_itemview: function() { oml_itemview: function() {
that.update(); that.updateElement();
} }
}); });
that.update = function() { that.updateElement = function() {
return that.options({ return that.options({
disabled: ui.itemView != 'book' disabled: ui.itemView != 'book'
}); });
}; };
return that.update(); return that.updateElement();
}; };

View File

@ -135,7 +135,7 @@ oml.ui.identifyDialog = function(data) {
Ox.Request.clearCache('find'); Ox.Request.clearCache('find');
oml.$ui.browser.reloadList(true); oml.$ui.browser.reloadList(true);
Ox.Request.clearCache(data.id); Ox.Request.clearCache(data.id);
oml.$ui.infoView.update(result.data); oml.$ui.infoView.updateElement(result.data);
}); });
} }
}) })

View File

@ -6,21 +6,21 @@ oml.ui.info = function() {
that = Ox.Element() that = Ox.Element()
.addClass('OxTextPage') .addClass('OxTextPage')
.css({ .css({
padding: '0 16px', padding: '0 16px',
textAlign: 'center', textAlign: 'center',
overflowY: 'auto' overflowY: 'auto'
}) })
.bindEvent({ .bindEvent({
oml_item: function() { oml_item: function() {
that.update(); that.updateElement();
}, },
oml_listselection: function() { oml_listselection: function() {
that.update(); that.updateElement();
} }
}); });
that.update = function() { that.updateElement = function() {
var id = ui.item || ui.listSelection[0]; var id = ui.item || ui.listSelection[0];
if (id) { if (id) {
oml.api.get({ oml.api.get({
@ -64,6 +64,6 @@ oml.ui.info = function() {
return that; return that;
}; };
return that.update(); return that.updateElement();
}; };

View File

@ -10,12 +10,12 @@ oml.ui.infoView = function(identifyData) {
.bindEvent({ .bindEvent({
oml_item: function() { oml_item: function() {
if (ui.item) { if (ui.item) {
that.update(ui.item); that.updateElement(ui.item);
} }
}, },
oml_listselection: function(data) { oml_listselection: function(data) {
if (data.value && data.value.length) { if (data.value && data.value.length) {
that.update(data.value[0]); that.updateElement(data.value[0]);
} }
} }
}), }),
@ -141,7 +141,7 @@ oml.ui.infoView = function(identifyData) {
.bindEvent({ .bindEvent({
click: function() { click: function() {
data.mediastate = 'transferring'; data.mediastate = 'transferring';
that.update(data, $data); that.updateElement(data, $data);
oml.api.download({id: ui.item}, function(result) { oml.api.download({id: ui.item}, function(result) {
// ... // ...
}); });
@ -158,7 +158,7 @@ oml.ui.infoView = function(identifyData) {
.bindEvent({ .bindEvent({
click: function(data) { click: function(data) {
data.mediastate = 'transferring'; data.mediastate = 'transferring';
that.update(data, $data); that.updateElement(data, $data);
oml.api.download(Ox.extend({ oml.api.download(Ox.extend({
id: ui.item, id: ui.item,
}, data.id == ':' ? {} : { }, data.id == ':' ? {} : {
@ -192,9 +192,9 @@ oml.ui.infoView = function(identifyData) {
.bindEvent({ .bindEvent({
click: function() { click: function() {
data.mediastate = 'unavailable'; data.mediastate = 'unavailable';
that.update(data, $data); that.updateElement(data, $data);
oml.api.cancelDownload({id: ui.item}, function() { oml.api.cancelDownload({id: ui.item}, function() {
that.update(ui.item, $data); that.updateElement(ui.item, $data);
}); });
} }
}) })
@ -232,7 +232,7 @@ oml.ui.infoView = function(identifyData) {
}).show(); }).show();
} }
that.update = function(idOrData, $elements) { that.updateElement = function(idOrData, $elements) {
var data = Ox.isObject(idOrData) ? idOrData : null, var data = Ox.isObject(idOrData) ? idOrData : null,
id = data ? null : idOrData, id = data ? null : idOrData,
@ -509,7 +509,7 @@ oml.ui.infoView = function(identifyData) {
oml.api.edit(edit, function(result) { oml.api.edit(edit, function(result) {
Ox.Request.clearCache('find'); Ox.Request.clearCache('find');
oml.$ui.browser.reloadList(); oml.$ui.browser.reloadList();
that.update(result.data, $data); that.updateElement(result.data, $data);
}); });
} }
} }
@ -519,16 +519,16 @@ oml.ui.infoView = function(identifyData) {
}; };
if (!identifyData) { if (!identifyData) {
ui.item && that.update(ui.item); ui.item && that.updateElement(ui.item);
} else { } else {
that.update(identifyData, [$cover, $info]); that.updateElement(identifyData, [$cover, $info]);
} }
oml.bindEvent({ oml.bindEvent({
transfer: function(data) { transfer: function(data) {
if (data.id == ui.item && data.progress == 1) { if (data.id == ui.item && data.progress == 1) {
Ox.Request.clearCache(); // FIXME: too much Ox.Request.clearCache(); // FIXME: too much
that.update(ui.item, [$info, $data]); that.updateElement(ui.item, [$info, $data]);
} }
} }
}); });

View File

@ -30,17 +30,17 @@ oml.ui.itemViewButtons = function() {
}, },
oml_item: function() { oml_item: function() {
if (ui.item) { if (ui.item) {
that.update(); that.updateElement();
} else { } else {
that.disableButton('book'); that.disableButton('book');
} }
}, },
oml_itemview: function(data) { oml_itemview: function(data) {
that.update(); that.updateElement();
} }
}); });
that.update = function() { that.updateElement = function() {
var item = ui.item; var item = ui.item;
that.options({ that.options({
disabled: ui.itemView != 'book', disabled: ui.itemView != 'book',
@ -68,6 +68,6 @@ oml.ui.itemViewButtons = function() {
} }
}); });
return that.update(); return that.updateElement();
}; };

View File

@ -11,9 +11,50 @@ oml.ui.list = function() {
oml.$ui.previewDialog.close(); oml.$ui.previewDialog.close();
delete oml.$ui.previewDialog; delete oml.$ui.previewDialog;
}, },
copy: function(data) {
oml.clipboard.copy(data.ids, 'item');
},
copyadd: function(data) {
oml.clipboard.copy(data.ids, 'item');
},
cut: function(data) {
var listData = oml.getListData();
if (listData.editable && listData.type == 'static') {
oml.clipboard.copy(data.ids, 'item');
oml.doHistory('cut', data.ids, ui._list, function() {
oml.UI.set({listSelection: []});
oml.reloadList();
});
}
},
cutadd: function(data) {
var listData = oml.getListData();
if (listData.editable && listData.type == 'static') {
oml.clipboard.add(data.ids, 'item');
oml.doHistory('cut', data.ids, ui._list, function() {
oml.UI.set({listSelection: []});
oml.reloadList();
});
}
},
'delete': function() {
var listData = oml.getListData();
if (listData.editable && listData.type == 'static') {
oml.doHistory('delete', data.ids, ui._list, function() {
oml.UI.set({listSelection: []});
oml.reloadList();
});
}
},
init: function(data) { init: function(data) {
oml.$ui.statusbar.set('total', data); oml.$ui.statusbar.set('total', data);
}, },
key_control_delete: function() {
var listData = oml.getListData();
if (listData.own) {
oml.ui.deleteItemsDialog().open();
}
},
open: function(data) { open: function(data) {
oml.UI.set({ oml.UI.set({
item: data.ids[0], item: data.ids[0],
@ -32,7 +73,7 @@ oml.ui.list = function() {
} }
}); });
} else { } else {
oml.$ui.previewDialog.update(); oml.$ui.previewDialog.updateElement();
} }
}, },
resize: function(data) { resize: function(data) {
@ -65,6 +106,10 @@ oml.ui.list = function() {
oml.enableDragAndDrop(that); oml.enableDragAndDrop(that);
that.updateElement = function() {
that.reloadList(true);
};
return that; return that;
}; };

View File

@ -40,7 +40,7 @@ oml.ui.loadingIcon = function() {
} }
}; };
that.update = function(requests) { that.updateElement = function(requests) {
that[requests ? 'start' : 'stop'](); that[requests ? 'start' : 'stop']();
}; };

View File

@ -319,8 +319,30 @@ oml.ui.mainMenu = function() {
oml.UI.set({showFileInfo: value}); oml.UI.set({showFileInfo: value});
} else if (id == 'fileinfo') { } else if (id == 'fileinfo') {
oml.UI.set({fileInfo: value}); oml.UI.set({fileInfo: value});
} else if (id == 'sort') {
oml.UI.set({
listSort: [{
key: value,
operator: oml.getSortOperator(value)
}]
});
} else if (id == 'order') {
oml.UI.set({
listSort: [{
key: ui.listSort[0].key,
operator: value == 'ascending' ? '+' : '-'
}]
});
} else if (id == 'find') {
if (value) {
oml.$ui.findSelect.value(value);
if (ui._findState.key == 'advanced') {
// fixme: autocomplete function doesn't get updated
pandora.$ui.findInput.options({placeholder: ''});
}
}
} else { } else {
Ox.print('MAIN MENU DOES NOT YET HANDLE', id); Ox.print('MAIN MENU DOES NOT YET HANDLE', id, data);
} }
}, },
click: function(data) { click: function(data) {
@ -441,6 +463,9 @@ oml.ui.mainMenu = function() {
that.options('menus')[0].element.trigger('click'); that.options('menus')[0].element.trigger('click');
} }
}, },
key_control_shift_f: function() {
Ox.print('FIXME: NOT IMPLEMENTED')
},
key_control_shift_w: function() { key_control_shift_w: function() {
if (!oml.hasDialogOrScreen()) { if (!oml.hasDialogOrScreen()) {
oml.UI.set({ oml.UI.set({
@ -628,7 +653,7 @@ oml.ui.mainMenu = function() {
id: 'deletefromlibrary', id: 'deletefromlibrary',
title: Ox._('Delete {0} from Library...', [selectionItemName]), title: Ox._('Delete {0} from Library...', [selectionItemName]),
disabled: !canDelete, disabled: !canDelete,
keyboard: 'shift delete' keyboard: 'control delete'
}, },
{}, {},
{ {
@ -716,19 +741,19 @@ oml.ui.mainMenu = function() {
id: 'editlist', id: 'editlist',
title: Ox._('Edit List...'), title: Ox._('Edit List...'),
keyboard: 'return', keyboard: 'return',
disabled: !isOwnList disabled: !isList || !isOwnList
}, },
{ {
id: 'deletelist', id: 'deletelist',
title: Ox._('Delete List...'), title: Ox._('Delete List...'),
keyboard: 'delete', keyboard: 'delete',
disabled: !isOwnList disabled: !isList || !isOwnList
} }
]) ])
}; };
} }
that.update = function(menu) { that.updateElement = function(menu) {
( (
menu ? Ox.makeArray(menu) : ['listMenu', 'editMenu'] menu ? Ox.makeArray(menu) : ['listMenu', 'editMenu']
).forEach(function(menu) { ).forEach(function(menu) {

View File

@ -91,13 +91,13 @@
oml.clipboard = Ox.Clipboard(); oml.clipboard = Ox.Clipboard();
oml.history = Ox.History(); oml.history = Ox.History();
oml.$ui.appPanel = oml.ui.appPanel().appendTo(Ox.$body); oml.$ui.appPanel = oml.ui.appPanel().appendTo(Ox.$body);
oml.$ui.loadingIcon.update(Ox.Request.requests()); oml.$ui.loadingIcon.updateElement(Ox.Request.requests());
Ox.Request.bindEvent({ Ox.Request.bindEvent({
error: function(data) { error: function(data) {
oml.$ui.errorDialog = oml.ui.errorDialog().update(data).open(); oml.$ui.errorDialog = oml.ui.errorDialog().updateElement(data).open();
}, },
request: function(data) { request: function(data) {
oml.$ui.loadingIcon.update(data.requests); oml.$ui.loadingIcon.updateElement(data.requests);
} }
}); });
if (oml.user.preferences.extensions) { if (oml.user.preferences.extensions) {

View File

@ -23,10 +23,10 @@ oml.ui.openButton = function() {
} }
}); });
that.update = function() { that.updateElement = function() {
return that.options({disabled: ui.listSelection.length == 0}); return that.options({disabled: ui.listSelection.length == 0});
}; };
return that.update(); return that.updateElement();
}; };

View File

@ -297,7 +297,7 @@ oml.ui.preferencesDialog = function() {
}, },
'oml_part.preferences': function() { 'oml_part.preferences': function() {
if (ui.page == 'preferences') { if (ui.page == 'preferences') {
that.update(); that.updateElement();
} }
} }
}); });
@ -308,7 +308,7 @@ oml.ui.preferencesDialog = function() {
$helpElement.show(); $helpElement.show();
} }
that.update = function() { that.updateElement = function() {
var $form, var $form,
$formTitle, $formTitle,
@ -439,6 +439,6 @@ oml.ui.preferencesDialog = function() {
}; };
return that.update(); return that.updateElement();
}; };

View File

@ -20,15 +20,15 @@ oml.ui.previewButton = function() {
oml.$ui.list[data.value ? 'openPreview' : 'closePreview'](); oml.$ui.list[data.value ? 'openPreview' : 'closePreview']();
}, },
oml_listselection: function() { oml_listselection: function() {
that.update(); that.updateElement();
} }
}); });
that.update = function() { that.updateElement = function() {
return that.options({disabled: ui.listSelection.length == 0}); return that.options({disabled: ui.listSelection.length == 0});
}; };
return that.update(); return that.updateElement();
}; };

View File

@ -52,7 +52,7 @@ oml.ui.previewDialog = function() {
}; };
} }
that.update = function() { that.updateElement = function() {
oml.api.get({ oml.api.get({
id: Ox.last($list.options('selected')), id: Ox.last($list.options('selected')),
keys: ['coverRatio', 'id', 'modified', 'title'] keys: ['coverRatio', 'id', 'modified', 'title']
@ -87,6 +87,6 @@ oml.ui.previewDialog = function() {
return that; return that;
}; };
return that.update(); return that.updateElement();
}; };

View File

@ -22,7 +22,7 @@ oml.ui.rightPanel = function() {
.bindEvent({ .bindEvent({
resize: function(data) { resize: function(data) {
that.options({size: data.size}); that.options({size: data.size});
oml.$ui.filtersOuterPanel.update(); oml.$ui.filtersOuterPanel.updateElement();
oml.$ui.itemViewPanel.options({size: data.size}); oml.$ui.itemViewPanel.options({size: data.size});
}, },
oml_item: function(data) { oml_item: function(data) {

View File

@ -18,10 +18,7 @@ oml.ui.sortElement = function() {
change: function(data) { change: function(data) {
var key = data.value; var key = data.value;
oml.UI.set({ oml.UI.set({
listSort: [{ listSort: [{key: key, operator: oml.getSortOperator(key)}]
key: key,
operator: oml.getSortOperator(key)
}]
}); });
} }
}), }),
@ -54,7 +51,7 @@ oml.ui.sortElement = function() {
}) })
.bindEvent({ .bindEvent({
oml_listsort: function() { oml_listsort: function() {
that.update(); that.updateElement();
} }
}); });
@ -66,7 +63,7 @@ oml.ui.sortElement = function() {
return Ox._(ui.listSort[0].operator == '+' ? 'Ascending' : 'Descending'); return Ox._(ui.listSort[0].operator == '+' ? 'Ascending' : 'Descending');
} }
that.update = function() { that.updateElement = function() {
$sortSelect.value(ui.listSort[0].key); $sortSelect.value(ui.listSort[0].key);
$orderButton.options({ $orderButton.options({
title: getButtonTitle(), title: getButtonTitle(),
@ -75,6 +72,6 @@ oml.ui.sortElement = function() {
return that; return that;
}; };
return that.update(); return that.updateElement();
}; };

View File

@ -519,7 +519,7 @@ oml.ui.usersDialog = function() {
} }
function updateUsers(callback) { function updateUsers(callback) {
Ox.Request.clearCache('getUsers');
oml.api.getUsers(function(result) { oml.api.getUsers(function(result) {
users = result.data.users; users = result.data.users;
@ -582,7 +582,7 @@ oml.ui.usersDialog = function() {
} }
that.update = function() { that.updateElement = function() {
that.options({ that.options({
content: Ox.LoadingScreen().start() content: Ox.LoadingScreen().start()
@ -592,6 +592,6 @@ oml.ui.usersDialog = function() {
}; };
return that.update(); return that.updateElement();
}; };

View File

@ -283,7 +283,7 @@ oml.enableDragAndDrop = function($list, canMove) {
editable: data.editable || ( editable: data.editable || (
data.type == 'library' data.type == 'library'
&& drag.source.user != username && drag.source.user != username
&& data.user == 'username' && data.user == username
), ),
selected: data.id == ui._list selected: data.id == ui._list
}, data); }, data);
@ -773,6 +773,8 @@ oml.getUsersAndLists = function(callback) {
nickname: username, nickname: username,
online: oml.user.online online: oml.user.online
}]; }];
Ox.Request.clearCache('getUsers');
Ox.Request.clearCache('getLists');
oml.api.getUsers(function(result) { oml.api.getUsers(function(result) {
users = users.concat( users = users.concat(
result.data.users.filter(function(user) { result.data.users.filter(function(user) {
@ -793,13 +795,15 @@ oml.getUsersAndLists = function(callback) {
)); ));
}); });
lists = lists.map(function(list) { lists = lists.map(function(list) {
// FIXME: 'editable' is notoriously vague
return Ox.extend(list, { return Ox.extend(list, {
editable: list.user == username && list.type == 'static', editable: list.user == username && list.type == 'static',
own: list.user == username,
title: (list.user ? list.user + ': ' : '') + list.name title: (list.user ? list.user + ': ' : '') + list.name
}); });
}) })
if (!ui.lists) { if (!ui.lists) {
oml.$ui.mainMenu.update(); oml.$ui.mainMenu.updateElement();
} }
ui._lists = lists; ui._lists = lists;
Ox.print('UI._LISTS', JSON.stringify(ui._lists)); Ox.print('UI._LISTS', JSON.stringify(ui._lists));
@ -829,17 +833,19 @@ oml.resizeListFolders = function() {
var width = oml.getListFoldersWidth(), var width = oml.getListFoldersWidth(),
columnWidth = width - 58; columnWidth = width - 58;
oml.$ui.librariesList oml.$ui.librariesList
.resizeColumn('name', columnWidth) .css({width: width + 'px'})
.css({width: width + 'px'}); .resizeColumn('name', columnWidth);
Ox.forEach(oml.$ui.folder, function($folder, index) { Ox.forEach(oml.$ui.folder, function($folder, index) {
$folder.css({width: width + 'px'}); $folder.css({width: width + 'px'});
Ox.print('SHOULD BE:', width);
oml.$ui.libraryList[index] oml.$ui.libraryList[index]
.resizeColumn('name', columnWidth) .css({width: width + 'px'})
.css({width: width + 'px'}); .resizeColumn('name', columnWidth);
oml.$ui.folderList[index] oml.$ui.folderList[index]
.resizeColumn('name', columnWidth) .css({width: width + 'px'})
.css({width: width + 'px'}); .resizeColumn('name', columnWidth);
}); });
/*
oml.$ui.librariesList oml.$ui.librariesList
.$body.find('.OxContent') .$body.find('.OxContent')
.css({width: width + 'px'}); .css({width: width + 'px'});
@ -851,6 +857,7 @@ oml.resizeListFolders = function() {
.$body.find('.OxContent') .$body.find('.OxContent')
.css({width: width + 'px'}); .css({width: width + 'px'});
}) })
*/
}; };
oml.updateFilterMenus = function() { oml.updateFilterMenus = function() {

View File

@ -7,16 +7,16 @@ oml.ui.viewer = function() {
that = Ox.Element() that = Ox.Element()
.bindEvent({ .bindEvent({
oml_item: function(data) { oml_item: function(data) {
that.update(); that.updateElement();
}, },
oml_itemview: function(data) { oml_itemview: function(data) {
that.update(); that.updateElement();
} }
}), }),
$iframe; $iframe;
that.update = function() { that.updateElement = function() {
if (ui.item && ui.itemView == 'book') { if (ui.item && ui.itemView == 'book') {
$iframe = $iframe || Ox.Element('<iframe>').css({ $iframe = $iframe || Ox.Element('<iframe>').css({
width: '100%', width: '100%',
@ -30,6 +30,6 @@ oml.ui.viewer = function() {
return that; return that;
}; };
return that.update(); return that.updateElement();
}; };

View File

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