This commit is contained in:
j 2014-05-19 17:00:33 +02:00
parent 1436b14003
commit 75a14fed1e
18 changed files with 251 additions and 121 deletions

View File

@ -110,7 +110,8 @@
"title": "Extension", "title": "Extension",
"type": "string", "type": "string",
"columnWidth": 80, "columnWidth": 80,
"sort": true "sort": true,
"find": true
}, },
{ {
"id": "size", "id": "size",
@ -319,6 +320,7 @@
"username": "" "username": ""
}, },
"ui": { "ui": {
"coverSize": 256,
"fileInfo": "extension", "fileInfo": "extension",
"filters": [ "filters": [
{"id": "author", "sort": [{"key": "items", "operator": "-"}]}, {"id": "author", "sort": [{"key": "items", "operator": "-"}]},

4
ctl
View File

@ -90,8 +90,8 @@ if [ "$1" == "update" ]; then
cd $BASE/$NAME cd $BASE/$NAME
git pull git pull
find . -name '*.pyc' -exec rm "{}" \; find . -name '*.pyc' -exec rm "{}" \;
$0 setup python2 oml setup
$0 update_static > /dev/null python2 oml update_static > /dev/null
exit exit
fi fi

View File

@ -151,7 +151,8 @@ class Changelog(db.Model):
if not i: if not i:
i = Item.get_or_create(itemid, info) i = Item.get_or_create(itemid, info)
i.modified = datetime.fromtimestamp(float(timestamp)) i.modified = datetime.fromtimestamp(float(timestamp))
i.users.append(user) if user not in i.users:
i.users.append(user)
i.update() i.update()
return True return True

View File

@ -70,7 +70,6 @@ def api_acceptPeering(app, user_id, username, message):
user.info['username'] = username user.info['username'] = username
user.info['message'] = message user.info['message'] = message
user.update_peering(True, username) user.update_peering(True, username)
trigger_event('peering.accept', user.json())
state.nodes.queue('add', user.id) state.nodes.queue('add', user.id)
return True return True
return False return False

View File

@ -11,6 +11,7 @@ import gzip
import urllib2 import urllib2
from datetime import datetime from datetime import datetime
import os import os
import time
import ox import ox
import ed25519 import ed25519
@ -30,7 +31,8 @@ logger = logging.getLogger('oml.nodes')
ENCODING='base64' ENCODING='base64'
class Node(object): class Node(Thread):
_running = True
_cert = None _cert = None
online = False online = False
download_speed = 0 download_speed = 0
@ -42,10 +44,36 @@ class Node(object):
self.user_id = user.id self.user_id = user.id
key = str(user.id) key = str(user.id)
self.vk = ed25519.VerifyingKey(key, encoding=ENCODING) self.vk = ed25519.VerifyingKey(key, encoding=ENCODING)
self.go_online()
logger.debug('new Node %s online=%s', self.user_id, self.online) logger.debug('new Node %s online=%s', self.user_id, self.online)
self._q = Queue()
Thread.__init__(self)
self.daemon = True
self.start()
self._ping = PeriodicCallback(self.ping, 120000) self._ping = PeriodicCallback(self.ping, 120000)
self._ping.start() self._ping.start()
self.ping()
def run(self):
with self._app.app_context():
while self._running:
action = self._q.get()
if not self._running:
break
if action == 'go_online' or not self.online:
self._go_online()
else:
self.online = self.can_connect()
def join(self):
self._running = False
self.ping()
return Thread.join(self)
def ping(self):
self._q.put('')
def go_online(self):
self._q.put('go_online')
@property @property
def url(self): def url(self):
@ -148,30 +176,26 @@ class Node(object):
def can_connect(self): def can_connect(self):
try: try:
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) logger.debug('try to connect to %s', self.url)
s.settimeout(1) r = self._opener.open(self.url, timeout=1)
s.connect((self.host, self.port)) c = r.read()
s.close() logger.debug('ok')
return True return True
except: except:
pass pass
logger.debug('failed')
return False return False
def ping(self): def _go_online(self):
with self._app.app_context():
if self.online:
self.online = self.can_connect()
else:
self.go_online()
def go_online(self):
self.resolve() self.resolve()
u = self.user u = self.user
logger.debug('go_online peer=%s queued=%s (%s)', u.peered, u.queued, u.id)
if u.peered or u.queued: if u.peered or u.queued:
try: try:
self.online = False self.online = False
logger.debug('type to connect to %s at [%s]:%s', self.user_id, self.host, self.port) logger.debug('try to connect to %s at [%s]:%s', self.user_id, self.host, self.port)
if self.can_connect(): if self.can_connect():
logger.debug('connected to [%s]:%s', self.host, self.port)
self.online = True self.online = True
if u.queued: if u.queued:
logger.debug('queued peering event pending=%s peered=%s', u.pending, u.peered) logger.debug('queued peering event pending=%s peered=%s', u.pending, u.peered)
@ -184,12 +208,14 @@ class Node(object):
self.peering('removePeering') self.peering('removePeering')
if self.online: if self.online:
self.pullChanges() self.pullChanges()
logger.debug('connected to %s', self.user_id)
except: except:
logger.debug('failed to connect to %s', self.user_id, exc_info=1) logger.debug('failed to connect to %s', self.user_id, exc_info=1)
self.online = False self.online = False
else: else:
self.online = False self.online = False
self.trigger_status()
def trigger_status(self):
trigger_event('status', { trigger_event('status', {
'id': self.user_id, 'id': self.user_id,
'online': self.online 'online': self.online
@ -210,10 +236,7 @@ class Node(object):
r = self.request('pushChanges', changes) r = self.request('pushChanges', changes)
except: except:
self.online = False self.online = False
trigger_event('status', { self.trigger_status()
'id': self.user_id,
'online': self.online
})
r = False r = False
logger.debug('pushedChanges %s %s', r, self.user_id) logger.debug('pushedChanges %s %s', r, self.user_id)
@ -230,9 +253,11 @@ class Node(object):
u.save() u.save()
else: else:
logger.debug('peering failed? %s %s', action, r) logger.debug('peering failed? %s %s', action, r)
if action in ('cancelPeering', 'rejectPeering', 'removePeering'): if action in ('cancelPeering', 'rejectPeering', 'removePeering'):
self.online = False self.online = False
else:
self.go_online()
trigger_event('peering.%s'%action.replace('Peering', ''), u.json())
return True return True
def download(self, item): def download(self, item):
@ -336,7 +361,7 @@ class Nodes(Thread):
self._nodes[user_id] = Node(self, User.get_or_create(user_id)) self._nodes[user_id] = Node(self, User.get_or_create(user_id))
else: else:
if not self._nodes[user_id].online: if not self._nodes[user_id].online:
self._nodes[user_id].go_online() self._nodes[user_id].ping()
def run(self): def run(self):
with self._app.app_context(): with self._app.app_context():
@ -351,4 +376,6 @@ class Nodes(Thread):
def join(self): def join(self):
self._running = False self._running = False
self._q.put(None) self._q.put(None)
for node in self._nodes.values():
node.join()
return Thread.join(self) return Thread.join(self)

View File

@ -42,7 +42,7 @@ class CertValidatingHTTPSConnection(httplib.HTTPConnection):
if not self._ValidateCertificateFingerprint(cert): if not self._ValidateCertificateFingerprint(cert):
raise InvalidCertificateException(self.fingerprint, cert, raise InvalidCertificateException(self.fingerprint, cert,
'fingerprint mismatch') 'fingerprint mismatch')
logger.debug('CIPHER %s VERSION %s', self.sock.cipher(), self.sock.ssl_version) #logger.debug('CIPHER %s VERSION %s', self.sock.cipher(), self.sock.ssl_version)
class VerifiedHTTPSHandler(urllib2.HTTPSHandler): class VerifiedHTTPSHandler(urllib2.HTTPSHandler):
def __init__(self, **kwargs): def __init__(self, **kwargs):

View File

@ -76,7 +76,6 @@ class User(db.Model):
def update_peering(self, peered, username=None): def update_peering(self, peered, username=None):
was_peering = self.peered was_peering = self.peered
self.queued = True
if peered: if peered:
self.pending = '' self.pending = ''
if username: if username:
@ -90,6 +89,7 @@ class User(db.Model):
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.peered = True
self.queued = True
self.save() self.save()
else: else:
self.pending = '' self.pending = ''

View File

@ -86,18 +86,19 @@ oml.ui.findElement = function() {
} }
}, },
submit: function(data) { submit: function(data) {
var scope = oml.$ui.findInSelect.value(), // FIXME: oml.$ui.findInSelect.value() is undefined
var scope = oml.$ui.findInSelect.options('value'),
key = oml.$ui.findSelect.value(), key = oml.$ui.findSelect.value(),
conditions = [].concat( conditions = [].concat(
scope == 'list' ? [{ scope == 'list' ? [{
key: 'list', key: 'list',
value: ui._list, operator: '==',
operator: '==' value: ui._list
}] : [], }] : [],
scope == 'user' ? [{ scope == 'user' ? [{
key: 'list', key: 'list',
value: ui._list.split(':')[0], operator: '==',
operator: '==' value: ui._list.split(':')[0] + ':'
}] : [], }] : [],
data.value ? [{ data.value ? [{
key: key, key: key,
@ -158,22 +159,29 @@ oml.ui.findElement = function() {
} }
function renderFindInSelect() { function renderFindInSelect() {
var scope = !ui._list ? 'all' var items = [
: Ox.endsWith(ui._list, ':') ? 'user' {id: 'all', title: Ox._('Find In: All Libraries')},
: 'list'; {id: 'user', title: Ox._('Find In: This Library')},
var $select = Ox.Select({ {id: 'list', title: Ox._('Find In: This List')}
],
scope = !ui._list ? 'all'
: Ox.endsWith(ui._list, ':') ? 'user'
: 'list',
$select = Ox.Select({
items: [ items: [
{id: 'all', title: Ox._('Find In: All Libraries')}, items[0],
].concat(scope != 'all' ? [ ].concat(scope != 'all' ? [
{id: 'user', title: Ox._('Find In: This Library')}, items[1],
] : []).concat(scope == 'list' ? [ ] : []).concat(scope == 'list' ? [
{id: 'list', title: Ox._('Find In: This List')} items[2]
] : []), ] : []),
max: 1,
min: 1,
overlap: 'right', overlap: 'right',
style: 'squared', style: 'squared',
title: scope == 'all' ? 'data' : scope, title: scope == 'all' ? 'data' : scope,
type: 'image', type: 'image',
tooltip: Ox._('Find: FIXME'), tooltip: Ox.getObjectById(items, scope).title,
value: scope value: scope
}) })
.bindEvent({ .bindEvent({

View File

@ -16,7 +16,10 @@ oml.ui.folders = function() {
//overflowY: 'auto', //overflowY: 'auto',
}) })
.bindEvent({ .bindEvent({
oml_find: selectList oml_find: selectList,
oml_showfolder: function() {
oml.resizeListFolders();
}
}); });
function getFind(list) { function getFind(list) {
@ -120,7 +123,7 @@ oml.ui.folders = function() {
userIndex[user.nickname] = index; userIndex[user.nickname] = index;
oml.$ui.folder[index] = Ox.CollapsePanel({ oml.$ui.folder[index] = Ox.CollapsePanel({
collapsed: false, collapsed: !ui.showFolder[user.nickname],
extras: [ extras: [
oml.ui.statusIcon(user, index), oml.ui.statusIcon(user, index),
{}, {},
@ -263,6 +266,7 @@ oml.ui.folders = function() {
}); });
oml.resizeListFolders(); // FIXME: DOESN'T WORK
selectList(); selectList();
}); });
@ -272,7 +276,6 @@ oml.ui.folders = function() {
}; };
that.updateItems = function(items) { that.updateItems = function(items) {
Ox.print('UPDATE ITEMS', items);
var $list; var $list;
if (arguments.length == 0) { if (arguments.length == 0) {
oml.getLists(function(lists) { oml.getLists(function(lists) {
@ -306,6 +309,7 @@ oml.ui.folders = function() {
}) })
.css({height: items.length * 16 + 'px'}) .css({height: items.length * 16 + 'px'})
.size(); .size();
oml.resizeFolders();
callback && callback(); callback && callback();
}); });
}; };
@ -316,10 +320,17 @@ oml.ui.folders = function() {
that.updateItems(); that.updateItems();
} }
}, },
change: function(data) {
Ox.print('got change event')
},
'peering.accept': function(data) { 'peering.accept': function(data) {
Ox.print('peering.accept reload list')
Ox.Request.clearCache('getUsers');
that.updateElement(); that.updateElement();
}, },
'peering.remove': function(data) { 'peering.remove': function(data) {
Ox.print('peering.remove reload list')
Ox.Request.clearCache('getUsers');
that.updateElement(); that.updateElement();
} }
}); });

View File

@ -4,6 +4,8 @@ oml.ui.infoView = function(identifyData) {
var ui = oml.user.ui, var ui = oml.user.ui,
css = getCSS(ui.coverSize),
that = Ox.Element() that = Ox.Element()
.addClass('OxTextPage') .addClass('OxTextPage')
.css({overflowY: 'auto'}) .css({overflowY: 'auto'})
@ -25,7 +27,7 @@ oml.ui.infoView = function(identifyData) {
position: 'absolute', position: 'absolute',
left: '16px', left: '16px',
top: '16px', top: '16px',
width: '256px' width: css.cover.width
}) })
.appendTo(that), .appendTo(that),
@ -33,7 +35,7 @@ oml.ui.infoView = function(identifyData) {
.addClass('OxSelectable') .addClass('OxSelectable')
.css({ .css({
position: 'absolute', position: 'absolute',
left: '288px', left: css.info.left,
right: !identifyData ? '176px' : 16 + Ox.UI.SCROLLBAR_SIZE + 'px', right: !identifyData ? '176px' : 16 + Ox.UI.SCROLLBAR_SIZE + 'px',
top: '16px' top: '16px'
}) })
@ -55,6 +57,28 @@ oml.ui.infoView = function(identifyData) {
.appendTo(that); .appendTo(that);
} }
function getCSS(size, ratio) {
var width = Math.round(ratio >= 1 ? size : size * ratio),
height = Math.round(ratio <= 1 ? size : size / ratio),
left = size == 256 ? Math.floor((size - width) / 2) : 0;
return {
cover: {
width: size + 'px'
},
info: {
left: (size == 256 ? size + 32 : width + 48) + 'px'
},
image: {
left: left + 'px',
width: width + 'px',
height: height + 'px'
},
reflection: {
top: height + 'px'
}
};
}
function getImageSize(size, ratio) { function getImageSize(size, ratio) {
var width = Math.round(ratio >= 1 ? size : size * ratio), var width = Math.round(ratio >= 1 ? size : size * ratio),
height = Math.round(ratio <= 1 ? size : size / ratio), height = Math.round(ratio <= 1 ? size : size / ratio),
@ -82,19 +106,6 @@ oml.ui.infoView = function(identifyData) {
function identify(data) { function identify(data) {
oml.ui.identifyDialog(data).open(); oml.ui.identifyDialog(data).open();
return;
$identifyPanel.select('id');
$identifyDialog.open();
identify(data);
function identify(data) {
oml.api.identify(data, function(result) {
$identifyList.options({
items: result.data.items.map(function(item, index) {
return Ox.extend(item, {index: index});
})
});
});
}
} }
function renderMediaButton(data) { function renderMediaButton(data) {
@ -213,23 +224,29 @@ oml.ui.infoView = function(identifyData) {
return $element; return $element;
} }
function updateCover(size, ratio) { function toggleCoverSize(ratio) {
var width = Math.round(ratio >= 1 ? size : size * ratio), var coverSize = ui.coverSize == 256 ? 512 : 256,
height = Math.round(ratio <= 1 ? size : size / ratio), css = getCSS(coverSize, ratio);
left = Math.floor((size - width) / 2); //$cover.animate(css.cover, 250);
$image.css({ $info.animate(css.info, 250);
left: left + 'px', $image.animate(css.image, 250);
width: width + 'px', $reflectionImage.animate(css.image, 250);
height: height + 'px' $reflection.animate(css.reflection, 250);
}).show(); /*
$reflectionImage.css({ $reflectionGradient.animate({
left: left + 'px', width: iconSize + 'px',
width: width + 'px', height: iconSize / 2 + 'px'
height: height + 'px' }, 250);
}); */
$reflection.css({
top: height + 'px' oml.UI.set({coverSize: coverSize});
}).show(); }
function updateCover(ratio) {
var css = getCSS(ui.coverSize, ratio);
$image.css(css.image).show();
$reflectionImage.css(css.image);
$reflection.css(css.reflection).show();
} }
that.updateElement = function(idOrData, $elements) { that.updateElement = function(idOrData, $elements) {
@ -257,10 +274,10 @@ oml.ui.infoView = function(identifyData) {
var $mediaButton, var $mediaButton,
isEditable = !data.mainid && data.mediastate == 'available', isEditable = !data.mainid && data.mediastate == 'available',
src = !identifyData src = !identifyData
? '/' + data.id + '/cover256.jpg?' + data.modified ? '/' + data.id + '/cover512.jpg?' + data.modified
: data.cover, : data.cover,
ratio = data.coverRatio || oml.config.coverRatio, ratio = data.coverRatio || oml.config.coverRatio,
size = 256, size = ui.coverSize,
reflectionSize = Math.round(size / 2); reflectionSize = Math.round(size / 2);
$elements.forEach(function($element) { $elements.forEach(function($element) {
@ -269,11 +286,14 @@ oml.ui.infoView = function(identifyData) {
if ($element == $cover) { if ($element == $cover) {
$image = $('<img>') $image = Ox.Element({
element: '<img>',
tooltip: '' // TODO
})
.on({ .on({
load: function() { load: function() {
var ratio = $image[0].width / $image[0].height; ratio = $image[0].width / $image[0].height;
updateCover(size, ratio); updateCover(ratio);
} }
}) })
.attr({src: src}) .attr({src: src})
@ -281,6 +301,11 @@ oml.ui.infoView = function(identifyData) {
position: 'absolute' position: 'absolute'
}) })
.hide() .hide()
.bindEvent({
singleclick: function() {
toggleCoverSize(ratio);
}
})
.appendTo($cover); .appendTo($cover);
$reflection = $('<div>') $reflection = $('<div>')

View File

@ -17,7 +17,7 @@ oml.ui.leftPanel = function() {
collapsed: !oml.user.ui.showInfo, collapsed: !oml.user.ui.showInfo,
collapsible: true, collapsible: true,
element: oml.$ui.info = oml.ui.info(), element: oml.$ui.info = oml.ui.info(),
size: ui.sidebarSize, size: oml.getInfoHeight(),
tooltip: Ox._('info') + ' <span class="OxBright">' tooltip: Ox._('info') + ' <span class="OxBright">'
+ Ox.SYMBOLS.SHIFT + 'I</span>' + Ox.SYMBOLS.SHIFT + 'I</span>'
} }

View File

@ -12,15 +12,15 @@ oml.ui.list = function() {
delete oml.$ui.previewDialog; delete oml.$ui.previewDialog;
}, },
copy: function(data) { copy: function(data) {
oml.clipboard.copy(data.ids, 'item'); oml.clipboard.copy(data.ids, 'book');
}, },
copyadd: function(data) { copyadd: function(data) {
oml.clipboard.copy(data.ids, 'item'); oml.clipboard.copy(data.ids, 'book');
}, },
cut: function(data) { cut: function(data) {
var listData = oml.getListData(); var listData = oml.getListData();
if (listData.editable && listData.type == 'static') { if (listData.editable && listData.type == 'static') {
oml.clipboard.copy(data.ids, 'item'); oml.clipboard.copy(data.ids, 'book');
oml.doHistory('cut', data.ids, ui._list, function() { oml.doHistory('cut', data.ids, ui._list, function() {
oml.UI.set({listSelection: []}); oml.UI.set({listSelection: []});
oml.$ui.folders.updateElement(); oml.$ui.folders.updateElement();
@ -31,7 +31,7 @@ oml.ui.list = function() {
cutadd: function(data) { cutadd: function(data) {
var listData = oml.getListData(); var listData = oml.getListData();
if (listData.editable && listData.type == 'static') { if (listData.editable && listData.type == 'static') {
oml.clipboard.add(data.ids, 'item'); oml.clipboard.add(data.ids, 'book');
oml.doHistory('cut', data.ids, ui._list, function() { oml.doHistory('cut', data.ids, ui._list, function() {
oml.UI.set({listSelection: []}); oml.UI.set({listSelection: []});
oml.$ui.folders.updateElement(); oml.$ui.folders.updateElement();
@ -96,6 +96,15 @@ oml.ui.list = function() {
oml.$ui.previewDialog.updateElement(); oml.$ui.previewDialog.updateElement();
} }
}, },
paste: function(data) {
var items = oml.clipboard.paste();
if (items.length && oml.clipboard.type() == 'book' && oml.getListData().editable) {
oml.doHistory('paste', items, ui._list, function() {
oml.UI.set({listSelection: items});
oml.reloadList();
});
}
},
resize: function(data) { resize: function(data) {
// this is the resize event of the split panel // this is the resize event of the split panel
that.size(); that.size();

View File

@ -76,7 +76,7 @@ oml.ui.listDialog = function() {
// FIXME: UGLY // FIXME: UGLY
listNames[listNames.indexOf(listData.name)] = value; listNames[listNames.indexOf(listData.name)] = value;
listData.name = value; listData.name = value;
// // ...
oml.api.editList({ oml.api.editList({
id: ui._list, id: ui._list,
name: value name: value
@ -118,4 +118,4 @@ oml.ui.listDialog = function() {
return that; return that;
}; };

View File

@ -379,6 +379,24 @@ oml.ui.mainMenu = function() {
oml.UI.set({listSelection: []}); oml.UI.set({listSelection: []});
} else if (id == 'invertselection') { } else if (id == 'invertselection') {
oml.$ui.list.invertSelection(); oml.$ui.list.invertSelection();
} else if (Ox.contains(['cut', 'cutadd'], id)) {
var action = data.id == 'cut' ? 'copy' : 'add';
fromMenu = true;
oml.clipboard[action](ui.listSelection, 'item');
oml.doHistory('cut', ui.listSelection, ui._list, function() {
oml.UI.set({listSelection: []});
oml.reloadList();
});
} else if (Ox.contains(['copy', 'copyadd'], id)) {
var action = data.id == 'copy' ? 'copy' : 'add';
fromMenu = true;
oml.clipboard[action](ui.listSelection, 'item');
} else if (id == 'paste') {
var items = oml.clipboard.paste();
oml.doHistory('paste', items, ui._list, function() {
oml.UI.set({listSelection: items});
oml.reloadList();
});
} else if (data.id == 'clearclipboard') { } else if (data.id == 'clearclipboard') {
oml.clipboard.clear(); oml.clipboard.clear();
} else if (data.id == 'delete') { } else if (data.id == 'delete') {
@ -542,7 +560,7 @@ oml.ui.mainMenu = function() {
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 && clipboardType == 'book',
canDelete = 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(),
@ -783,6 +801,24 @@ oml.ui.mainMenu = function() {
}; };
} }
oml.clipboard.bindEvent(function(data, event) {
if (Ox.contains(['add', 'copy', 'clear'], event)) {
that.replaceMenu('editMenu', getEditMenu());
}
if (Ox.contains(['add', 'copy', 'paste'], event) && !fromMenu) {
that.highlightMenu('editMenu');
}
fromMenu = false;
});
oml.history.bindEvent(function(data, event) {
that.replaceMenu('editMenu', getEditMenu());
if (Ox.contains(['undo', 'redo'], event) && !fromMenu) {
that.highlightMenu('editMenu');
}
fromMenu = false;
});
that.updateElement = function(menu) { that.updateElement = function(menu) {
( (
menu ? Ox.makeArray(menu) : ['listMenu', 'editMenu', 'findMenu'] menu ? Ox.makeArray(menu) : ['listMenu', 'editMenu', 'findMenu']

View File

@ -90,6 +90,9 @@
oml.URL.init().parse(function() { oml.URL.init().parse(function() {
oml.clipboard = Ox.Clipboard(); oml.clipboard = Ox.Clipboard();
oml.history = Ox.History(); oml.history = Ox.History();
Ox.$window.on({
resize: oml.resizeWindow
});
oml.$ui.appPanel = oml.ui.appPanel().appendTo(Ox.$body); oml.$ui.appPanel = oml.ui.appPanel().appendTo(Ox.$body);
oml.$ui.loadingIcon.updateElement(Ox.Request.requests()); oml.$ui.loadingIcon.updateElement(Ox.Request.requests());
Ox.Request.bindEvent({ Ox.Request.bindEvent({
@ -100,7 +103,7 @@
oml.$ui.loadingIcon.updateElement(data.requests); oml.$ui.loadingIcon.updateElement(data.requests);
} }
}); });
if (oml.user.preferences.extensions) { if (oml.user.preferences.extensions) {
try { try {
eval(oml.user.preferences.extensions) eval(oml.user.preferences.extensions)
} catch(e) {} } catch(e) {}

View File

@ -17,22 +17,30 @@ oml.ui.rightPanel = function() {
], ],
orientation: 'horizontal', orientation: 'horizontal',
selected: !ui.item ? 'list' : 'item', selected: !ui.item ? 'list' : 'item',
size: window.innerWidth - ui.showSidebar * ui.sidebarSize - 1 size: getSize()
}) })
.bindEvent({ .bindEvent({
resize: function(data) { resize: function(data) {
Ox.print('::RESIZING', data.size);
that.options({size: data.size}); that.options({size: data.size});
oml.$ui.filtersOuterPanel.updateElement(); 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) {
Ox.print('rightPanel, oml_item', data);
if (!!data.value != !!data.previousValue) { if (!!data.value != !!data.previousValue) {
that.options({selected: !ui.item ? 'list' : 'item'}); that.options({selected: !ui.item ? 'list' : 'item'});
} }
} }
}); });
function getSize() {
return window.innerWidth - ui.showSidebar * ui.sidebarSize - 1;
}
that.updateElement = function() {
return that.triggerEvent('resize', {size: getSize()});
};
return that; return that;
}; };

View File

@ -44,21 +44,20 @@ oml.ui.statusIcon = function(user, index) {
} }
function getStatus(data) { function getStatus(data) {
return !oml.user.online && index ? 'unknown' return !oml.user.online ? 'unknown'
: data.online ? 'connected' : data.online ? 'connected'
: 'disconnected'; : 'disconnected';
} }
function render() { function render() {
var color = { var color = {
connected: [[64, 255, 64], [0, 192, 0]], connected: [[64, 255, 64], [0, 192, 0]],
disconnected: [[255, 64, 64], [192, 0, 0]], disconnected: [[255, 64, 64], [192, 0, 0]],
transferring: [[64, 255, 255], [0, 192, 192]], transferring: [[64, 255, 255], [0, 192, 192]],
unknown: [[255, 255, 64], [192, 192, 0]] unknown: [[255, 255, 64], [192, 192, 0]]
}[status].map(function(rgb) { }[status].map(function(rgb) {
return 'rgb(' + rgb.join(', ') + ')'; return 'rgb(' + rgb.join(', ') + ')';
}).join(', '); }).join(', ');
that.options({ that.options({
tooltip: Ox._({ tooltip: Ox._({
connected: 'Connected', connected: 'Connected',
@ -68,7 +67,6 @@ oml.ui.statusIcon = function(user, index) {
}).css({ }).css({
background: '-webkit-linear-gradient(bottom, ' + color + ')', background: '-webkit-linear-gradient(bottom, ' + color + ')',
}); });
that.find('div').css({ that.find('div').css({
background: '-webkit-linear-gradient(top, ' + color + ')', background: '-webkit-linear-gradient(top, ' + color + ')',
}); });
@ -85,4 +83,5 @@ oml.ui.statusIcon = function(user, index) {
} }
return that; return that;
}; };

View File

@ -740,9 +740,9 @@ oml.getListData = function(list) {
oml.getListFoldersHeight = function() { oml.getListFoldersHeight = function() {
var ui = oml.user.ui; var ui = oml.user.ui;
return Object.keys(ui.showFolder).reduce(function(value, id, index) { return oml.$ui.folder.reduce(function(value, $folder, index) {
var items = oml.$ui.folderList[index].options('items').length; var items = oml.$ui.folderList[index].options('items').length;
return value + 16 + ui.showFolder[id] * (1 + items) * 16; return value + 16 + !$folder.options('collapsed') * (1 + items) * 16;
}, 16); }, 16);
}; };
@ -895,8 +895,7 @@ oml.hasDialogOrScreen = function() {
}; };
oml.reloadList = function() { oml.reloadList = function() {
Ox.print('RELOAD LIST NOT IMPLEMENTED') oml.$ui.list.updateElement();
// ...
}; };
oml.resizeFilters = function() { oml.resizeFilters = function() {
@ -905,6 +904,16 @@ oml.resizeFilters = function() {
oml.resizeListFolders = function() { oml.resizeListFolders = function() {
// FIXME: does this have to be here? // FIXME: does this have to be here?
/*
Ox.print(
'RESIZE LIST FOLDERS',
'SIDEBAR', oml.user.ui.sidebarSize,
'WIDTH', oml.getListFoldersWidth(),
'HEIGHT', oml.getListFoldersHeight(),
'INFO HEIGHT', oml.getInfoHeight(),
'AVAILABLE HEIGHT', window.innerHeight - 20 - 24 - 1 - oml.user.ui.showInfo * oml.getInfoHeight()
)
*/
var width = oml.getListFoldersWidth(), var width = oml.getListFoldersWidth(),
columnWidth = width - 58; columnWidth = width - 58;
oml.$ui.librariesList oml.$ui.librariesList
@ -919,19 +928,12 @@ oml.resizeListFolders = function() {
.css({width: width + 'px'}) .css({width: width + 'px'})
.resizeColumn('name', columnWidth); .resizeColumn('name', columnWidth);
}); });
/* };
oml.$ui.librariesList
.$body.find('.OxContent') oml.resizeWindow = function() {
.css({width: width + 'px'}); oml.$ui.leftPanel && oml.$ui.leftPanel.size(2, oml.getInfoHeight());
Ox.forEach(oml.$ui.folder, function($folder, index) { oml.resizeListFolders();
oml.$ui.libraryList[index] oml.$ui.rightPanel && oml.$ui.rightPanel.updateElement();
.$body.find('.OxContent')
.css({width: width + 'px'});
oml.$ui.folderList[index]
.$body.find('.OxContent')
.css({width: width + 'px'});
})
*/
}; };
oml.updateFilterMenus = function() { oml.updateFilterMenus = function() {