lots of stuff (part2)

This commit is contained in:
j 2014-05-21 02:02:39 +02:00
parent feddea0ccd
commit 0d77cfd158
14 changed files with 767 additions and 578 deletions

View file

@ -1,5 +1,5 @@
{ {
"coverRatio": 0.75, "iconRatio": 0.75,
"itemKeys": [ "itemKeys": [
{ {
"id": "*", "id": "*",
@ -110,6 +110,7 @@
"title": "Extension", "title": "Extension",
"type": "string", "type": "string",
"columnWidth": 80, "columnWidth": 80,
"format": {"type": "upper", "args": []},
"sort": true "sort": true
}, },
{ {
@ -194,51 +195,44 @@
"sort": true "sort": true
}, },
{ {
"id": "isbn10", "id": "isbn",
"title": "ISBN-10", "title": "ISBN",
"type": "string", "type": ["string"],
"columnWidth": 96,
"sort": true
},
{
"id": "isbn13",
"title": "ISBN-13",
"type": "string",
"columnWidth": 96, "columnWidth": 96,
"sort": true "sort": true
}, },
{ {
"id": "asin", "id": "asin",
"title": "ASIN", "title": "ASIN",
"type": "string", "type": ["string"],
"columnWidth": 96, "columnWidth": 96,
"sort": true "sort": true
}, },
{ {
"id": "lccn", "id": "lccn",
"title": "LCCN", "title": "LCCN",
"type": "string", "type": ["string"],
"columnWidth": 96, "columnWidth": 96,
"sort": true "sort": true
}, },
{ {
"id": "olid", "id": "olid",
"title": "OLID", "title": "OLID",
"type": "string", "type": ["string"],
"columnWidth": 96, "columnWidth": 96,
"sort": true "sort": true
}, },
{ {
"id": "oclc", "id": "oclc",
"title": "OCLC", "title": "OCLC",
"type": "string", "type": ["string"],
"columnWidth": 96, "columnWidth": 96,
"sort": true "sort": true
}, },
{ {
"id": "mainid", "id": "primaryid",
"title": "Main ID", "title": "Primary ID",
"type": "string" "type": ["string"]
}, },
{ {
"id": "random", "id": "random",
@ -319,7 +313,6 @@
"username": "" "username": ""
}, },
"ui": { "ui": {
"coverSize": 256,
"fileInfo": "extension", "fileInfo": "extension",
"filters": [ "filters": [
{"id": "author", "sort": [{"key": "items", "operator": "-"}]}, {"id": "author", "sort": [{"key": "items", "operator": "-"}]},
@ -331,6 +324,8 @@
"filtersSize": 176, "filtersSize": 176,
"find": {"conditions": [], "operator": "&"}, "find": {"conditions": [], "operator": "&"},
"icons": "cover", "icons": "cover",
"iconInfo": "extension",
"iconSize": 256,
"item": "", "item": "",
"itemView": "info", "itemView": "info",
"listColumns": ["title", "author", "publisher", "date"], "listColumns": ["title", "author", "publisher", "date"],
@ -354,9 +349,9 @@
"section": "books", "section": "books",
"showBrowser": true, "showBrowser": true,
"showDebugMenu": false, "showDebugMenu": false,
"showFileInfo": true,
"showFolder": {}, "showFolder": {},
"showFilters": true, "showFilters": true,
"showIconInfo": true,
"showInfo": true, "showInfo": true,
"showSection": { "showSection": {
"notifications": { "notifications": {

View file

@ -0,0 +1,38 @@
"""empty message
Revision ID: 1fe914156ac0
Revises: 4480ecc50e04
Create Date: 2014-05-20 18:29:36.352416
"""
# revision identifiers, used by Alembic.
revision = '1fe914156ac0'
down_revision = '4480ecc50e04'
from alembic import op
import sqlalchemy as sa
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.add_column('item', sa.Column('sort_isbn', sa.String(length=1000), nullable=True))
op.create_index(op.f('ix_item_sort_isbn'), 'item', ['sort_isbn'], unique=False)
#op.drop_column('item', 'sort_isbn13')
#op.drop_column('item', 'sort_isbn10')
#op.drop_index('ix_item_sort_isbn10', table_name='item')
#op.drop_index('ix_item_sort_isbn13', table_name='item')
### end Alembic commands ###
pass
def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_index('ix_item_sort_isbn13', 'item', ['sort_isbn13'], unique=False)
op.create_index('ix_item_sort_isbn10', 'item', ['sort_isbn10'], unique=False)
op.drop_index(op.f('ix_item_sort_isbn'), table_name='item')
op.add_column('item', sa.Column('sort_isbn10', sa.VARCHAR(length=1000), nullable=True))
op.add_column('item', sa.Column('sort_isbn13', sa.VARCHAR(length=1000), nullable=True))
op.drop_column('item', 'sort_isbn')
### end Alembic commands ###

View file

@ -0,0 +1,44 @@
"""empty message
Revision ID: 3822b1700859
Revises: 1fe914156ac0
Create Date: 2014-05-20 23:25:34.942115
"""
# revision identifiers, used by Alembic.
revision = '3822b1700859'
down_revision = '1fe914156ac0'
from alembic import op
import sqlalchemy as sa
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_table('metadata',
sa.Column('created', sa.DateTime(), nullable=True),
sa.Column('modified', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('key', sa.String(length=256), nullable=True),
sa.Column('value', sa.String(length=256), nullable=True),
sa.Column('data', sa.PickleType(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
#op.drop_column(u'item', 'sort_isbn13')
#op.drop_column(u'item', 'sort_isbn10')
#op.create_index(op.f('ix_item_sort_isbn'), 'item', ['sort_isbn'], unique=False)
#op.drop_index('ix_item_sort_isbn10', table_name='item')
#op.drop_index('ix_item_sort_isbn13', table_name='item')
### end Alembic commands ###
def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_index('ix_item_sort_isbn13', 'item', ['sort_isbn13'], unique=False)
op.create_index('ix_item_sort_isbn10', 'item', ['sort_isbn10'], unique=False)
op.drop_index(op.f('ix_item_sort_isbn'), table_name='item')
op.add_column(u'item', sa.Column('sort_isbn10', sa.VARCHAR(length=1000), nullable=True))
op.add_column(u'item', sa.Column('sort_isbn13', sa.VARCHAR(length=1000), nullable=True))
op.drop_table('metadata')
### end Alembic commands ###

View file

@ -0,0 +1,35 @@
"""empty message
Revision ID: 3ea9f03f386f
Revises: 3822b1700859
Create Date: 2014-05-20 23:37:03.959948
"""
# revision identifiers, used by Alembic.
revision = '3ea9f03f386f'
down_revision = '3822b1700859'
from alembic import op
import sqlalchemy as sa
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_table('metadata')
op.create_table('metadata',
sa.Column('created', sa.DateTime(), nullable=True),
sa.Column('modified', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('key', sa.String(length=256), nullable=True),
sa.Column('value', sa.String(length=256), nullable=True),
sa.Column('data', sa.PickleType(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
### end Alembic commands ###
def downgrade():
pass
### commands auto generated by Alembic - please adjust! ###
### end Alembic commands ###

View file

@ -6,13 +6,14 @@ oml.ui.browser = function() {
that = Ox.IconList({ that = Ox.IconList({
centered: true, centered: true,
defaultRatio: oml.config.coverRatio, defaultRatio: oml.config.iconRatio,
draggable: true, draggable: true,
item: function(data, sort, size) { item: function(data, sort, size) {
var color = oml.getFileInfoColor(ui.fileInfo, data).map(function(rgb) { var color = oml.getIconInfoColor(ui.iconInfo, data).map(function(rgb) {
return rgb.concat(0.8); return rgb.concat(0.8);
}), }),
ratio = data.coverRatio || oml.config.coverRatio, ratio = (ui.icons == 'cover' ? data.coverRatio : data.previewRatio)
|| oml.config.iconRatio,
width = Math.round(ratio >= 1 ? size : size * ratio), width = Math.round(ratio >= 1 ? size : size * ratio),
height = Math.round(ratio <= 1 ? size : size / ratio), height = Math.round(ratio <= 1 ? size : size / ratio),
sortKey = sort[0].key, sortKey = sort[0].key,
@ -22,7 +23,7 @@ oml.ui.browser = function() {
); );
size = size || 64; size = size || 64;
return { return {
extra: ui.showFileInfo ? $('<div>') extra: ui.showIconInfo ? $('<div>')
.css({ .css({
width: width + 'px', width: width + 'px',
height: Math.round(size / 12.8) + 'px', height: Math.round(size / 12.8) + 'px',
@ -39,7 +40,7 @@ oml.ui.browser = function() {
WebkitTransform: 'rotate(45deg)' WebkitTransform: 'rotate(45deg)'
}) })
.html( .html(
ui.fileInfo == 'extension' ui.iconInfo == 'extension'
? data.extension.toUpperCase() ? data.extension.toUpperCase()
: Ox.formatValue(data.size, 'B') : Ox.formatValue(data.size, 'B')
) : null, ) : null,
@ -47,7 +48,7 @@ oml.ui.browser = function() {
id: data.id, id: data.id,
info: info, info: info,
title: data.title, title: data.title,
url: '/' + data.id + '/cover128.jpg', url: '/' + data.id + '/' + ui.icons + '128.jpg',
width: width width: width
}; };
}, },
@ -57,8 +58,8 @@ oml.ui.browser = function() {
}), callback); }), callback);
}, },
keys: [ keys: [
'author', 'coverRatio', 'extension', 'id', 'author', 'coverRatio', 'extension', 'id', 'mediastate',
'mediastate', 'size', 'textsize', 'title' 'previewRatio', 'size', 'textsize', 'title'
], ],
max: 1, max: 1,
min: 1, min: 1,
@ -87,6 +88,15 @@ oml.ui.browser = function() {
oml_find: function() { oml_find: function() {
that.reloadList(); that.reloadList();
}, },
oml_iconinfo: function() {
that.reloadList(true);
},
oml_icons: function() {
that.reloadList(true);
},
oml_showiconinfo: function() {
that.reloadList(true);
},
oml_item: function(data) { oml_item: function(data) {
if (data.value && !data.previousValue) { if (data.value && !data.previousValue) {
that.gainFocus(); that.gainFocus();

View file

@ -130,7 +130,7 @@ oml.ui.folders = function() {
Ox.Button({ Ox.Button({
style: 'symbol', style: 'symbol',
title: 'info', title: 'info',
tooltip: Ox._(!index ? 'Preferences' : 'Profile'), tooltip: Ox._(!index ? 'Preferences...' : 'Profile...'),
type: 'image' type: 'image'
}) })
.bindEvent({ .bindEvent({

View file

@ -5,13 +5,14 @@ oml.ui.gridView = function() {
var ui = oml.user.ui, var ui = oml.user.ui,
that = Ox.IconList({ that = Ox.IconList({
defaultRatio: oml.config.coverRatio, defaultRatio: oml.config.iconRatio,
draggable: true, draggable: true,
item: function(data, sort, size) { item: function(data, sort, size) {
var color = oml.getFileInfoColor(ui.fileInfo, data).map(function(rgb) { var color = oml.getIconInfoColor(ui.iconInfo, data).map(function(rgb) {
return rgb.concat(0.8); return rgb.concat(0.8);
}), }),
ratio = data.coverRatio || oml.config.coverRatio, ratio = (ui.icons == 'cover' ? data.coverRatio : data.previewRatio)
|| oml.config.iconRatio,
width = Math.round(ratio >= 1 ? size : size * ratio), width = Math.round(ratio >= 1 ? size : size * ratio),
height = Math.round(ratio <= 1 ? size : size / ratio), height = Math.round(ratio <= 1 ? size : size / ratio),
sortKey = sort[0].key, sortKey = sort[0].key,
@ -21,7 +22,7 @@ oml.ui.gridView = function() {
); );
size = size || 128; size = size || 128;
return { return {
extra: ui.showFileInfo ? $('<div>') extra: ui.showIconInfo ? $('<div>')
.css({ .css({
width: width + 'px', width: width + 'px',
height: Math.round(size / 12.8) + 'px', height: Math.round(size / 12.8) + 'px',
@ -38,7 +39,7 @@ oml.ui.gridView = function() {
WebkitTransform: 'rotate(45deg)' WebkitTransform: 'rotate(45deg)'
}) })
.html( .html(
ui.fileInfo == 'extension' ui.iconInfo == 'extension'
? data.extension.toUpperCase() ? data.extension.toUpperCase()
: Ox.formatValue(data.size, 'B') : Ox.formatValue(data.size, 'B')
) : null, ) : null,
@ -46,7 +47,7 @@ oml.ui.gridView = function() {
id: data.id, id: data.id,
info: info, info: info,
title: data.title, title: data.title,
url: '/' + data.id + '/cover128.jpg', url: '/' + data.id + '/' + ui.icons + '128.jpg',
width: width width: width
}; };
}, },
@ -56,13 +57,24 @@ oml.ui.gridView = function() {
}), callback); }), callback);
}, },
keys: [ keys: [
'author', 'coverRatio', 'extension', 'id', 'author', 'coverRatio', 'extension', 'id', 'mediastate',
'mediastate', 'size', 'textsize', 'title' 'previewRatio', 'size', 'textsize', 'title'
], ],
selected: ui.listSelection, selected: ui.listSelection,
size: 128, size: 128,
sort: ui.listSort, sort: ui.listSort,
unique: 'id' unique: 'id'
})
.bindEvent({
oml_iconinfo: function() {
that.reloadList(true);
},
oml_icons: function() {
that.reloadList(true);
},
oml_showiconinfo: function() {
that.reloadList(true);
}
}); });
return that; return that;

View file

@ -4,8 +4,8 @@ oml.ui.identifyDialog = function(data) {
var ui = oml.user.ui, var ui = oml.user.ui,
ids = [ lookupItems = [
'isbn10', 'isbn13', 'asin', 'lccn', 'oclc', 'olid' 'isbn', 'asin', 'lccn', 'oclc', 'olid'
].map(function(id) { ].map(function(id) {
return { return {
id: id, id: id,
@ -13,48 +13,113 @@ oml.ui.identifyDialog = function(data) {
}; };
}), }),
keys = [ selected = data.primaryid ? 'lookup' : 'find',
'title', 'author', 'publisher', 'date', 'edition', 'language'
].map(function(id) {
var key = Ox.getObjectById(oml.config.itemKeys, id);
return {
format: key.format,
id: id,
title: key.title,
visible: true
};
}),
originalData = Ox.clone(data, true), $lookupForm = Ox.Element(),
selected = data.mainid ? 'id' : 'title', $lookupSelect = Ox.Select({
items: lookupItems,
overlap: 'right',
max: 1,
min: 1,
value: data.primaryid ? data.primaryid[0] : 'isbn',
width: 128
})
.bindEvent({
change: function(data) {
$lookupInput.focusInput(true);
}
}),
idValue, titleValue, $lookupInput = Ox.Input({
value: data.primaryid ? data.primaryid[1] : '',
width: 480
})
.bindEvent({
change: function(data) {
// ...
},
submit: lookupMetadata
}),
$idInputs, $idButtons = {}, $lookupButton = Ox.Button({
overlap: 'left',
title: Ox._('Look Up'),
width: 128
})
.bindEvent({
click: lookupMetadata
}),
$idForm = renderIdForm(data), $lookupElement = Ox.FormElementGroup({
elements: [
Ox.FormElementGroup({
elements: [
$lookupSelect,
$lookupInput
],
float: 'left'
}),
$lookupButton
],
float: 'right'
})
.css({
margin: '16px'
})
.appendTo($lookupForm),
$idPreview = data.mainid $lookupPreview = data.primaryid
? oml.ui.infoView(data) ? oml.ui.infoView(data)
: Ox.Element(), : Ox.Element(),
$idPanel = Ox.SplitPanel({ $lookupPanel = Ox.SplitPanel({
elements: [ elements: [
{element: Ox.Element().append($idForm), size: 96}, {element: $lookupForm, size: 48},
{element: $idPreview} {element: $lookupPreview}
], ],
orientation: 'vertical' orientation: 'vertical'
}), }),
$titleInputs, $titleButtons = {}, $findForm = Ox.Element(),
$titleForm = renderTitleForm(), $findInput = Ox.Input({
label: Ox._('Title, Author etc.'),
labelWidth: 128,
width: 608,
value: [data.title].concat(data.author || []).join(' ')
})
.bindEvent({
submit: findMetadata
}),
$titlePanel = Ox.SplitPanel({ $findButton = Ox.Button({
overlap: 'left',
title: Ox._('Find'),
width: 128
})
.bindEvent({
click: findMetadata
}),
$findElement = Ox.FormElementGroup({
elements: [
$findInput,
$findButton
],
float: 'right'
})
.css({
margin: '16px'
})
.appendTo($findForm),
$findList,
$findPanel = Ox.SplitPanel({
elements: [ elements: [
{element: $titleForm, size: 96}, {element: $findForm, size: 48},
{element: renderResults()} {element: renderResults([])}
], ],
orientation: 'vertical' orientation: 'vertical'
}), }),
@ -63,8 +128,8 @@ oml.ui.identifyDialog = function(data) {
$buttons = Ox.ButtonGroup({ $buttons = Ox.ButtonGroup({
buttons: [ buttons: [
{id: 'id', title: Ox._('Look Up by ID')}, {id: 'lookup', title: Ox._('Look Up by ID')},
{id: 'title', title: Ox._('Find by Title')} {id: 'find', title: Ox._('Find by Title')}
], ],
selectable: true, selectable: true,
value: selected value: selected
@ -78,14 +143,17 @@ oml.ui.identifyDialog = function(data) {
change: function(data) { change: function(data) {
selected = data.value; selected = data.value;
$innerPanel.options({selected: selected}); $innerPanel.options({selected: selected});
$updateButton.options({
disabled: selected == 'find' && !$findList
});
} }
}) })
.appendTo($bar), .appendTo($bar),
$innerPanel = Ox.SlidePanel({ $innerPanel = Ox.SlidePanel({
elements: [ elements: [
{id: 'id', element: $idPanel}, {id: 'lookup', element: $lookupPanel},
{id: 'title', element: $titlePanel} {id: 'find', element: $findPanel}
], ],
orientation: 'horizontal', orientation: 'horizontal',
selected: selected, selected: selected,
@ -100,43 +168,89 @@ oml.ui.identifyDialog = function(data) {
orientation: 'vertical' orientation: 'vertical'
}), }),
that = Ox.Dialog({ $metadataSelect = Ox.Select({
buttons: [ items: [
Ox.Button({ {id: 'original', title: Ox._('Show Original Metadata')},
id: 'dontupdate', {id: 'edited', title: Ox._('Show Edited Metadata')}
title: Ox._('No, Don\'t Update') ],
}) max: 1,
.bindEvent({ min: 1,
click: function() { value: 'edited',
that.close(); width: 192
})
.css({
margin: '4px'
})
.bindEvent({
change: function(data) {
if (selected == 'lookup') {
if (!$lookupButton.options('disabled')) {
$lookupButton.triggerEvent('click');
}
} else {
if ($findList) {
$findList.triggerEvent('select', {
ids: $findList.options('selected')
});
}
} }
}), }
Ox.Button({ }),
disabled: true,
id: 'update', $dontUpdateButton = Ox.Button({
title: Ox._('Yes, Update') id: 'dontupdate',
}) title: Ox._('No, Don\'t Update')
.bindEvent({ })
click: function() { .bindEvent({
Ox.print('$$$', idValue); click: function() {
var edit = Ox.extend( that.close();
{id: data.id}, }
$innerPanel.options('selected') == 'id' }),
? idValue || {mainid: ''}
: titleValue $updateButton = Ox.Button({
disabled: true,
id: 'update',
title: Ox._('Yes, Update')
})
.bindEvent({
click: function() {
// FIXME: Wrong if user messes with lookup elements before clicking update button
var primaryId;
if (selected == 'lookup') {
primaryId = [
$lookupSelect.value(),
$lookupInput.value()
];
} else {
primaryId = $findList.value(
$findList.options('selected')[0],
'primaryid'
); );
that.options({content: Ox.LoadingScreen().start()}); }
that.disableButtons(); that.options({content: Ox.LoadingScreen().start()});
Ox.print('VALUE SENT:', edit) that.disableButtons();
oml.api.edit(edit, function(result) { oml.api.edit({
id: data.id,
primaryid: primaryId
}, function(result) {
(
$metadataSelect.value() == 'original'
? oml.api.resetMetadata : Ox.noop
)({id: ui.item}, function(result) {
that.close(); that.close();
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.updateElement(data.id); oml.$ui.infoView.updateElement(data.id);
}); });
} });
}) }
}),
that = Ox.Dialog({
buttons: [
$dontUpdateButton,
$updateButton
], ],
closeButton: true, closeButton: true,
content: $outerPanel, content: $outerPanel,
@ -147,379 +261,126 @@ oml.ui.identifyDialog = function(data) {
width: 768 width: 768
}); });
$($metadataSelect.find('.OxButton')[0]).css({margin: 0});
$metadataSelect.appendTo($(that.find('.OxBar')[2]));
function disableButtons() { function disableButtons() {
Ox.forEach(selected == 'id' ? $idButtons : $titleButtons, function($button) { $lookupSelect.options('items').forEach(function(item) {
$button.options({disabled: true}); $lookupSelect.disableItem(item.id);
}); });
$lookupInput.options({disabled: true});
$lookupButton.options({disabled: true});
$findInput.options({disabled: true});
$findButton.options({disabled: true});
$metadataSelect.options('items').forEach(function(item) {
$metadataSelect.disableItem(item.id);
});
$updateButton.options({disabled: true});
} }
function findMetadata(data) { function enableButtons() {
$lookupSelect.options('items').forEach(function(item) {
$lookupSelect.enableItem(item.id);
});
$lookupInput.options({disabled: false});
$lookupButton.options({disabled: false});
$findInput.options({disabled: false});
$findButton.options({disabled: false});
$metadataSelect.options('items').forEach(function(item) {
$metadataSelect.enableItem(item.id);
});
$updateButton.options({disabled: false});
}
function findMetadata() {
disableButtons(); disableButtons();
$titlePanel.replaceElement(1, Ox.LoadingScreen().start()); $findPanel.replaceElement(1, Ox.LoadingScreen().start());
oml.api.findMetadata(data, function(result) { oml.api.findMetadata({
query: $findInput.value()
}, function(result) {
var items = result.data.items.map(function(item, index) { var items = result.data.items.map(function(item, index) {
return Ox.extend({index: (index + 1).toString()}, item); return Ox.extend({index: index.toString()}, item);
}); });
updateTitleButtons(); enableButtons();
$titlePanel.replaceElement(1, renderResults(items)); $updateButton.options({disabled: !items.length});
$findPanel.replaceElement(1, renderResults(items));
}); });
} }
function getMetadata(key, value) { function lookupMetadata() {
disableButtons(); disableButtons();
$idPanel.replaceElement(1, Ox.LoadingScreen().start()); $lookupPanel.replaceElement(1, Ox.LoadingScreen().start());
oml.api.getMetadata(Ox.extend({}, key, value), function(result) { oml.api.getMetadata(Ox.extend(
$idForm = renderIdForm(result.data); {includeEdits: $metadataSelect.value() == 'edited'},
$idPreview = Ox.isEmpty(data) ? Ox.Element() : oml.ui.infoView(result.data); $lookupSelect.value(),
$idPanel $lookupInput.value()
.replaceElement(0, $idForm) ), function(result) {
.replaceElement(1, $idPreview); enableButtons();
$updateButton.options({disabled: Ox.isEmpty(data)});
$lookupPreview = Ox.isEmpty(data)
? Ox.Element()
: oml.ui.infoView(result.data);
$lookupPanel.replaceElement(1, $lookupPreview);
}); });
} }
function idInputValues(key, values) {
var $input = $idInputs[ids.map(function(id) {
return id.id;
}).indexOf(key)];
if (Ox.isUndefined(values)) {
values = $input.options('elements').map(function($element) {
return $element.value();
});
} else {
$input.options('elements').forEach(function($element, index) {
$element.value(values[index]);
});
}
return values;
}
function isEmpty(data) {
return Ox.every(data, Ox.isEmpty);
}
function isOriginal(data) {
return Ox.every(Object.keys(data), function(key) {
return data[key] == originalData[key];
});
}
function renderIdForm(data) {
var $element = Ox.Element();
$idInputs = ids.map(function(id, index) {
return Ox.FormElementGroup({
elements: [
Ox.Checkbox({
overlap: 'right',
title: Ox._(id.title),
value: id.id == data.mainid,
width: 80
})
.bindEvent({
change: function(data) {
var value = $idInputs[index].options('elements')[1].value();
if (data.value) {
if (value) {
idValue = Ox.extend({}, id.id, value);
$idInputs.forEach(function($input, i) {
if (i != index) {
$input.options('elements')[0].value(false);
}
});
getMetadata(id.id, value, function() {
// ...
});
} else {
this.value(false);
}
} else {
this.value(true);
}
}
}),
Ox.Input({
value: data[id.id] || '',
width: 160
})
.bindEvent({
submit: function(data) {
if (data.value) {
idValue = Ox.extend({}, id.id, data.value);
$idInputs.forEach(function($input, i) {
$input.options('elements')[0].options({
disabled: true,
value: i == index
});
$input.options('elements')[1].options({
disabled: true
});
});
getMetadata(id.id, data.value, function() {
Ox.print('GOT METADATA');
updateIdButtons();
});
}
}
})
],
float: 'left'
})
.css({
position: 'absolute',
left: 16 + Math.floor(index / 2) * 248 + 'px',
top: 16 + (index % 2) * 24 + 'px'
})
.appendTo($element);
});
$idButtons.clear = Ox.Button({
title: Ox._('Clear'),
width: 64
})
.css({
position: 'absolute',
right: '160px',
top: '64px'
})
.bindEvent({
click: function() {
ids.forEach(function(id) {
idInputValues(id.id, [false, '']);
});
updateIdButtons();
}
})
.appendTo($element);
$idButtons.reset = Ox.Button({
disabled: true,
title: Ox._('Reset'),
width: 64
})
.css({
position: 'absolute',
right: '88px',
top: '64px'
})
.bindEvent({
click: function() {
ids.forEach(function(id) {
idInputValues(id.id, [
id.id == originalData.mainid,
originalData[id.id]
]);
});
updateIdButtons();
}
})
.appendTo($element);
$idButtons.find = Ox.Button({
title: Ox._('Look Up'),
width: 64
})
.css({
position: 'absolute',
right: '16px',
top: '64px'
})
.bindEvent({
click: function() {
var key, value;
Ox.forEach(ids, function(id) {
var values = idInputValues(id.id);
if (values[0]) {
key = id.id;
value = values[1];
return false;
}
});
getMetadata(key, value, function() {
// ...
})
Ox.print('NOT IMPLEMENTED')
}
})
.appendTo($element);
updateIdButtons();
return $element;
}
function renderResults(items) { function renderResults(items) {
var $list = Ox.TableList({ var $resultsPanel;
columns: [ if (items.length) {
{ $findList = Ox.TableList({
columns: [{
format: function(value, data) { format: function(value, data) {
return value return '<b>' + Ox.getObjectById(
? '<b>' + Ox.getObjectById(ids, value).title lookupItems, data.primaryid[0]
+ ':</b> ' + data[data.mainid] ).title + ':</b> ' + data.primaryid[1]
: '<b>No ID</b>'
}, },
id: 'mainid', id: 'index',
visible: true, visible: true,
width: 192 - Ox.UI.SCROLLBAR_SIZE width: 192 - Ox.UI.SCROLLBAR_SIZE
} }],
], items: items,
items: [{ keys: ['primaryid'].concat(lookupItems.map(function(item) {
'index': '0', return item.id;
'mainid': '' })),
}].concat(items || []), min: 1,
keys: ['mainid', 'isbn10', 'isbn13'], max: 1,
min: 1, scrollbarVisible: true,
max: 1, selected: ['0'],
scrollbarVisible: true, sort: [{key: 'index', operator: '+'}],
sort: [{key: 'index', operator: '+'}], unique: 'index'
unique: 'index' })
}) .bindEvent({
.bindEvent({ select: function(data) {
select: function(data) { var index = data.ids[0],
var index = data.ids[0], primaryId = $findList.value(index, 'primaryid');
mainid = $list.value(index, 'mainid'); Ox.print('EEEE', index, primaryId);
if (!mainid) { disableButtons();
titleValue = {}; $resultsPanel.replaceElement(1, Ox.LoadingScreen().start());
keys.forEach(function(key) { oml.api.getMetadata(Ox.extend(
titleValue[key.id] = titleInputValue(key.id); {includeEdits: $metadataSelect.value() == 'edited'},
primaryId[0],
primaryId[1]
), function(result) {
enableButtons();
$resultsPanel.replaceElement(1, oml.ui.infoView(result.data));
}); });
$results.replaceElement(1, oml.ui.infoView(titleValue));
} else {
titleValue = Ox.extend({}, mainid, $list.value(index, mainid));
$results.replaceElement(1, Ox.LoadingScreen().start());
oml.api.getMetadata(titleValue, function(result) {
if (index == $list.options('selected')[0]) {
$results.replaceElement(1, oml.ui.infoView(result.data));
that.options('buttons')[1].options({disabled: false});
}
});
} }
} }),
}), $resultsPanel = Ox.SplitPanel({
$results = Ox.SplitPanel({
elements: [ elements: [
{element: $list, size: 192}, {element: $findList || Ox.Element(), size: 192},
{element: Ox.Element()} {element: Ox.Element()}
], ],
orientation: 'horizontal' orientation: 'horizontal'
}); });
return $results; setTimeout(function() {
} $findList.triggerEvent('select', {ids: ['0']});
});
function renderTitleForm() {
var $element = Ox.Element();
$titleInputs = keys.map(function(key, index) {
return Ox.Input({
label: Ox._(key.title),
labelWidth: 80,
value: data[key.id],
width: 240
})
.css({
position: 'absolute',
left: 16 + Math.floor(index / 2) * 248 + 'px',
top: 16 + (index % 2) * 24 + 'px'
})
.bindEvent({
submit: function(data) {
$titleButtons.find.triggerEvent('click');
}
})
.appendTo($element);
});
$titleButtons.clear = Ox.Button({
title: Ox._('Clear'),
width: 64
})
.css({
position: 'absolute',
right: '160px',
top: '64px'
})
.bindEvent({
click: function() {
keys.forEach(function(key) {
titleInputValue(key.id, '');
});
updateTitleButtons();
}
})
.appendTo($element);
$titleButtons.reset = Ox.Button({
disabled: true,
title: Ox._('Reset'),
width: 64
})
.css({
position: 'absolute',
right: '88px',
top: '64px'
})
.bindEvent({
click: function() {
keys.forEach(function(key) {
titleInputValue(key.id, originalData[key.id]);
});
updateTitleButtons();
}
})
.appendTo($element);
$titleButtons.find = Ox.Button({
title: Ox._('Find'),
width: 64
})
.css({
position: 'absolute',
right: '16px',
top: '64px'
})
.bindEvent({
click: function() {
var data = {};
keys.forEach(function(key) {
data[key.id] = titleInputValue(key.id);
});
findMetadata(data);
}
})
.appendTo($element);
return $element;
}
function titleInputValue(key, value) {
var $input = $titleInputs[keys.map(function(key) {
return key.id;
}).indexOf(key)];
if (Ox.isUndefined(value)) {
value = $input.value();
if (key == 'author') {
value = value ? value.split(', ') : [];
}
} else { } else {
$input.value( $findList = void 0;
key == 'author' ? (value || []).join(', ') : value $resultsPanel = Ox.Element();
);
} }
return value; return $resultsPanel;
}
function updateIdButtons() {
var data = {}, empty, original;
ids.forEach(function(id) {
data[id.id] = idInputValues(id.id)[1];
});
empty = isEmpty(data);
original = isOriginal(data);
$idButtons.clear.options({disabled: empty});
$idButtons.reset.options({disabled: original});
$idButtons.find.options({disabled: empty});
that && that[original ? 'disableButton' : 'enableButton']('update');
}
function updateTitleButtons() {
var data = {}, empty, original;
keys.forEach(function(key) {
data[key.id] = titleInputValue(key.id);
});
empty = isEmpty(data);
original = isOriginal(data);
$titleButtons.clear.options({disabled: empty});
$titleButtons.reset.options({disabled: original});
$titleButtons.find.options({disabled: empty});
that[original ? 'disableButton' : 'enableButton']('update');
} }
return that; return that;

View file

@ -260,8 +260,8 @@ oml.ui.importExportDialog = function(selected) {
Ox.Select({ Ox.Select({
id: 'mode', id: 'mode',
items: [ items: [
{id: 'add', title: Ox._('Add (keep files in destination path)')}, {id: 'add', title: Ox._('Add (keep all exisiting files in destination path)')},
{id: 'replace', title: Ox._('Replace (delete files from destination path)')} {id: 'replace', title: Ox._('Replace (delete all existing files from destination path)')}
], ],
label: Ox._('Export Mode'), label: Ox._('Export Mode'),
labelWidth: 128, labelWidth: 128,

View file

@ -4,14 +4,17 @@ oml.ui.infoView = function(identifyData) {
var ui = oml.user.ui, var ui = oml.user.ui,
coverSize = identifyData ? 256 : ui.coverSize, iconSize = identifyData ? 256 : ui.iconSize,
css = getCSS(coverSize, oml.config.coverRatio), css = getCSS(iconSize, oml.config.iconRatio),
that = Ox.Element() that = Ox.Element()
.addClass('OxTextPage') .addClass('OxTextPage')
.css({overflowY: 'auto'}) .css({overflowY: 'auto'})
.bindEvent({ .bindEvent({
oml_icons: function() {
that.updateElement(ui.item, [$icon])
},
oml_item: function() { oml_item: function() {
if (ui.item) { if (ui.item) {
that.updateElement(ui.item); that.updateElement(ui.item);
@ -24,12 +27,12 @@ oml.ui.infoView = function(identifyData) {
} }
}), }),
$cover = Ox.Element() $icon = Ox.Element()
.css({ .css({
position: 'absolute', position: 'absolute',
left: '16px', left: '16px',
top: '16px', top: '16px',
width: css.cover.width width: css.icon.width
}) })
.appendTo(that), .appendTo(that),
@ -41,7 +44,7 @@ oml.ui.infoView = function(identifyData) {
right: !identifyData ? '176px' : 16 + Ox.UI.SCROLLBAR_SIZE + 'px', right: !identifyData ? '176px' : 16 + Ox.UI.SCROLLBAR_SIZE + 'px',
top: '16px' top: '16px'
}) })
[coverSize == 512 ? 'hide' : 'show']() [iconSize == 512 ? 'hide' : 'show']()
.appendTo(that), .appendTo(that),
$data, $data,
@ -65,7 +68,7 @@ oml.ui.infoView = function(identifyData) {
height = Math.round(ratio <= 1 ? size : size / ratio), height = Math.round(ratio <= 1 ? size : size / ratio),
left = size == 256 ? Math.floor((size - width) / 2) : 0; left = size == 256 ? Math.floor((size - width) / 2) : 0;
return { return {
cover: { icon: {
width: size + 'px' width: size + 'px'
}, },
info: { info: {
@ -82,34 +85,99 @@ oml.ui.infoView = function(identifyData) {
}; };
} }
function getImageSize(size, ratio) { function getIconTooltip() {
var width = Math.round(ratio >= 1 ? size : size * ratio), return !identifyData
height = Math.round(ratio <= 1 ? size : size / ratio), ? 'Click to see ' + (ui.iconSize == 256 ? 'large' : 'small')
left = Math.floor((size - width) / 2); + ' ' + ui.icons + ', doubleclick to see '
return {width: width, height: height, left: left}; + (ui.icons == 'cover' ? 'preview' : 'cover')
: '';
} }
function formatLight(str) { function formatLight(string) {
return '<span class="OxLight">' + str + '</span>'; return '<span class="OxLight">' + string + '</span>';
} }
function formatKey(key) { function formatKey(key) {
var item = Ox.getObjectById(oml.config.itemKeys, key); var item = Ox.getObjectById(oml.config.itemKeys, key);
return '<span style="font-weight: bold">' return '<span style="font-weight: bold">'
+ Ox._(Ox.toTitleCase(key)) + ':&nbsp;</span> '; + Ox._(Ox.toTitleCase(key)) + ':</span>&nbsp;';
} }
function formatValue(value, key, join) { function formatValue(value, key) {
value = Ox.encodeHTMLEntities(value);
return value ? (Ox.isArray(value) ? value : [value]).map(function(value) { return value ? (Ox.isArray(value) ? value : [value]).map(function(value) {
return key && !identifyData ? return key && !identifyData ?
'<a href="/' + key + '==' + value + '">' + value + '</a>' '<a href="/' + key + '==' + (
key == 'date' ? value.slice(0, 4) : value
) + '">' + value + '</a>'
: value; : value;
}).join(join || ', ') : ''; }).join('; ') : '';
} }
function identify(data) { function identify(data) {
oml.ui.identifyDialog(data).open(); oml.$ui.identifyDialog = oml.ui.identifyDialog(data).open();
}
function renderIdentifyButton(data) {
return Ox.FormElementGroup({
elements: [
Ox.Button({
disabled: data.mediastate != 'available',
title: Ox._('Identify Book...'),
width: 112
})
.bindEvent({
click: function() {
identify(data);
}
}),
data.mediastate == 'available' && data.primaryid
? Ox.Select({
items: Ox.flatten([
'isbn', 'asin', 'lccn', 'oclc', 'olid'
].map(function(key) {
return (data[key] || []).map(function(value) {
return {
id: key + ':' + value,
title: '<b>' + Ox.getObjectById(
oml.config.itemKeys, key
).title + ':</b> ' + value
};
});
})).concat([
{id: '', title: '<b>No ID</b>'}
]),
max: 1,
min: 1,
overlap: 'left',
title: 'select',
tooltip: Ox._('Set Primary ID'),
type: 'image',
value: data.primaryid.join(':')
})
.bindEvent({
click: function(data) {
Ox.print('####', data);
},
change: function(data) {
Ox.print('$$$', data);
oml.api.edit({
id: ui.item,
primaryid: data.value ? data.value.split(':') : ''
}, function(result) {
that.updateElement(result.data, [$data]);
});
}
})
: Ox.Button({
disabled: true,
overlap: 'left',
title: 'select',
type: 'image'
})
],
float: 'right'
})
.css({marginTop: '16px'});
} }
function renderMediaButton(data) { function renderMediaButton(data) {
@ -166,7 +234,7 @@ oml.ui.infoView = function(identifyData) {
disabled: !ui._lists, disabled: !ui._lists,
items: getListItems(), items: getListItems(),
overlap: 'left', overlap: 'left',
title: 'list', title: 'select',
tooltip: Ox._('Download Book to a List'), tooltip: Ox._('Download Book to a List'),
type: 'image' type: 'image'
}) })
@ -230,18 +298,19 @@ oml.ui.infoView = function(identifyData) {
function toggleCoverSize(ratio) { function toggleCoverSize(ratio) {
var css; var css;
coverSize = coverSize == 256 ? 512 : 256, iconSize = iconSize == 256 ? 512 : 256,
css = getCSS(coverSize, ratio); css = getCSS(iconSize, ratio);
//$cover.animate(css.cover, 250); //$icon.animate(css.icon, 250);
Ox.print('ANIMATE,', css)
$info.animate(css.info, 250); $info.animate(css.info, 250);
$image.animate(css.image, 250); $image.animate(css.image, 250);
$reflectionImage.animate(css.image, 250); $reflectionImage.animate(css.image, 250);
$reflection.animate(css.reflection, 250); $reflection.animate(css.reflection, 250);
oml.UI.set({coverSize: coverSize}); oml.UI.set({iconSize: iconSize});
} }
function updateCover(ratio) { function updateCover(ratio) {
var css = getCSS(coverSize, ratio); var css = getCSS(iconSize, ratio);
$image.css(css.image).show(); $image.css(css.image).show();
$reflectionImage.css(css.image); $reflectionImage.css(css.image);
$reflection.css(css.reflection).show(); $reflection.css(css.reflection).show();
@ -254,7 +323,7 @@ oml.ui.infoView = function(identifyData) {
$elements = $elements $elements = $elements
? Ox.makeArray($elements) ? Ox.makeArray($elements)
: [$cover, $info, $data]; : [$icon, $info, $data];
(data ? Ox.noop : oml.api.get)({ (data ? Ox.noop : oml.api.get)({
id: id, id: id,
@ -271,24 +340,27 @@ oml.ui.infoView = function(identifyData) {
Ox.print('BOOK DATA', data) Ox.print('BOOK DATA', data)
var $mediaButton, var $div,
isEditable = !data.mainid && data.mediastate == 'available', isEditable = data.mediastate == 'available' && !identifyData,
src = !identifyData src = !identifyData
? '/' + data.id + '/cover512.jpg?' + data.modified ? '/' + data.id + '/' + ui.icons + '512.jpg?' + data.modified
: data.cover, : data.cover,
ratio = data.coverRatio || oml.config.coverRatio, ratio = (
size = coverSize, ui.icons == 'cover' || identifyData
? data.coverRatio : data.previewRatio
) || oml.config.iconRatio,
size = iconSize,
reflectionSize = Math.round(size / 2); reflectionSize = Math.round(size / 2);
$elements.forEach(function($element) { $elements.forEach(function($element) {
$element.empty(); $element.empty();
if ($element == $cover) { if ($element == $icon) {
$image = Ox.Element({ $image = Ox.Element({
element: '<img>', element: '<img>',
tooltip: '' // TODO tooltip: getIconTooltip()
}) })
.on({ .on({
error: function() { error: function() {
@ -312,13 +384,21 @@ oml.ui.infoView = function(identifyData) {
}) })
.hide() .hide()
.bindEvent({ .bindEvent({
doubleclick: function() {
if (!identifyData) {
oml.UI.set({
icons: ui.icons == 'cover'
? 'preview' : 'cover'
});
}
},
singleclick: function() { singleclick: function() {
if (!identifyData) { if (!identifyData) {
toggleCoverSize(ratio); toggleCoverSize(ratio);
} }
} }
}) })
.appendTo($cover); .appendTo($icon);
$reflection = $('<div>') $reflection = $('<div>')
.addClass('OxReflection') .addClass('OxReflection')
@ -329,7 +409,7 @@ oml.ui.infoView = function(identifyData) {
overflow: 'hidden' overflow: 'hidden'
}) })
.hide() .hide()
.appendTo($cover); .appendTo($icon);
$reflectionImage = $('<img>') $reflectionImage = $('<img>')
.attr({src: src}) .attr({src: src})
@ -348,58 +428,130 @@ oml.ui.infoView = function(identifyData) {
} else if ($element == $info) { } else if ($element == $info) {
// -------- Title
$('<div>') $('<div>')
.css({ .css({
marginTop: '-2px', marginTop: '-2px'
fontSize: '13px',
fontWeight: 'bold'
}) })
.html( .append(
data.title ? Ox.encodeHTMLEntities(data.title) Ox.EditableContent({
: '<span class="OxLight">' clickLink: oml.clickLink,
+ Ox._('No Title') editable: isEditable,
+ '</span>' tooltip: isEditable ? oml.getEditTooltip() : '',
value: data.title || 'No Title'
})
.css({
fontWeight: 'bold',
fontSize: '13px'
})
.bindEvent({
submit: function(event) {
editMetadata('title', event.value);
}
})
) )
.appendTo($info); .appendTo($info);
if (data.author) { // -------- Author
$('<div>')
.css({
marginTop: '4px',
fontSize: '13px',
fontWeight: 'bold'
})
.html(formatValue(data.author, 'author'))
.appendTo($info);
}
if (data.place || data.publisher || data.date) { $('<div>')
$('<div>') .css({
.css({ marginTop: '2px'
marginTop: '8px' })
}) .append(
.html( Ox.EditableContent({
(formatValue(data.place, 'place', ' ; ')) clickLink: oml.clickLink,
+ (data.place && (data.publisher || data.date) ? ' : ' : '') editable: isEditable,
+ (formatValue(data.publisher, 'publisher')) format: function(value) {
+ (data.publisher && data.date ? ', ' : '') return formatValue(value.split('; '), 'author');
+ (data.date || '') },
) placeholder: formatLight(Ox._('Unknown Author')),
.appendTo($info); tooltip: isEditable ? oml.getEditTooltip() : '',
} value: data.author ? data.author.join('; ') : ''
})
.css({
marginBottom: '-3px',
fontWeight: 'bold',
fontSize: '13px'
})
.bindEvent({
submit: function(event) {
editMetadata('author', event.value);
}
})
)
.appendTo($info);
if (data.edition || data.language) { // -------- Place, Publisher, Date
$('<div>')
.css({ $div = $('<div>')
marginTop: '8px' .css({
marginTop: '4px',
})
.appendTo($info);
['place', 'publisher', 'date'].forEach(function(key, index) {
if (index) {
$('<span>').html(', ').appendTo($div);
}
$('<span>')
.html(formatKey(key))
.appendTo($div);
Ox.EditableContent({
clickLink: oml.clickLink,
editable: isEditable,
format: function(value) {
return formatValue(value.split('; '), key)
},
placeholder: formatLight('unknown'),
tooltip: isEditable ? oml.getEditTooltip() : '',
value: key == 'place'
? (data[key] ? data[key].join('; ') : [''])
: data[key] || ''
}) })
.html( .bindEvent({
(Ox.encodeHTMLEntities(data.edition || '')) submit: function(event) {
+ (data.edition && data.language ? '; ' : '') editMetadata(key, event.value);
+ (formatValue(data.language, 'language')) }
) })
.appendTo($info); .appendTo($div);
} });
// -------- Edition, Language, Pages
$div = $('<div>')
.css({
marginTop: '4px',
})
.appendTo($info);
['edition', 'language', 'pages'].forEach(function(key, index) {
if (index) {
$('<span>').html(', ').appendTo($div);
}
$('<span>')
.html(formatKey(key))
.appendTo($div);
Ox.EditableContent({
clickLink: oml.clickLink,
editable: isEditable,
format: function(value) {
return key == 'language'
? formatValue(value, key)
: value;
},
placeholder: formatLight('unknown'),
tooltip: isEditable ? oml.getEditTooltip() : '',
value: data[key] || ''
})
.bindEvent({
submit: function(event) {
editMetadata(key, event.value);
}
})
.appendTo($div);
});
// -------- Classification
if (data.classification) { if (data.classification) {
$('<div>') $('<div>')
@ -413,6 +565,8 @@ oml.ui.infoView = function(identifyData) {
.appendTo($info); .appendTo($info);
} }
// -------- Description
if (data.description) { if (data.description) {
$('<div>') $('<div>')
.css({ .css({
@ -427,10 +581,11 @@ oml.ui.infoView = function(identifyData) {
$('<div>').css({height: '16px'}).appendTo($info); $('<div>').css({height: '16px'}).appendTo($info);
oml.createLinks($info);
} else if ($element == $data) { } else if ($element == $data) {
$mediaButton = renderMediaButton(data) renderMediaButton(data).appendTo($data);
.appendTo($data);
$('<div>') $('<div>')
.addClass('OxSelectable') .addClass('OxSelectable')
@ -439,7 +594,7 @@ oml.ui.infoView = function(identifyData) {
}) })
.text( .text(
[ [
(data.extension || '???').toUpperCase(), // FIXME data.extension.toUpperCase(),
Ox.formatValue(data.size, 'B') Ox.formatValue(data.size, 'B')
].join(', ') ].join(', ')
) )
@ -462,24 +617,13 @@ oml.ui.infoView = function(identifyData) {
} }
}); });
Ox.Button({ renderIdentifyButton(data).appendTo($data);
disabled: data.mediastate != 'available',
title: Ox._('Identify Book...'),
width: 128
})
.css({marginTop: '16px'})
.bindEvent({
click: function() {
identify(data);
}
})
.appendTo($data);
[ [
'isbn10', 'isbn13', 'asin', 'lccn', 'oclc', 'olid' 'isbn', 'asin', 'lccn', 'oclc', 'olid'
].forEach(function(id, index) { ].forEach(function(id, index) {
var title; var title;
if (data[id]) { if (data[id] && !Ox.isEmpty(data[id])) {
title = Ox.getObjectById(oml.config.itemKeys, id).title; title = Ox.getObjectById(oml.config.itemKeys, id).title;
$('<div>') $('<div>')
.css({ .css({
@ -488,11 +632,19 @@ oml.ui.infoView = function(identifyData) {
}) })
.text(title) .text(title)
.appendTo($data); .appendTo($data);
Ox.EditableContent({ Ox.makeArray(data[id]/*FIXME!*/).forEach(function(value) {
editable: false, var isPrimary = data.primaryid[0] == id
value: data[id] && data.primaryid[1] == value;
}) Ox.Element({
.appendTo($data); tooltip: isPrimary ? 'Primary ID' : ''
})
.html(
Ox.encodeHTMLEntities(value) + (
isPrimary ? ' (*)' : ''
)
)
.appendTo($data);
});
} }
}); });
@ -502,16 +654,19 @@ oml.ui.infoView = function(identifyData) {
}); });
// FIXME: identify dialog should call this too
function editMetadata(key, value) { function editMetadata(key, value) {
var edit;
Ox.print('EM', key, value, data[key])
if (value != data[key]) { if (value != data[key]) {
edit = Ox.extend({id: ui.item}, key, value); var edit = {id: data.id};
if (Ox.contains(['author', 'place'], key)) {
edit[key] = value ? value.split('; ') : [];
} else {
edit[key] = value;
}
Ox.print('EDIT METADATA', key, value, edit);
oml.api.edit(edit, function(result) { oml.api.edit(edit, function(result) {
Ox.Request.clearCache('find'); oml.$ui.browser.value(
oml.$ui.browser.reloadList(); result.data.id, key, result.data[key]
//that.updateElement(result.data, $info); );
}); });
} }
} }
@ -523,7 +678,7 @@ oml.ui.infoView = function(identifyData) {
if (!identifyData) { if (!identifyData) {
ui.item && that.updateElement(ui.item); ui.item && that.updateElement(ui.item);
} else { } else {
that.updateElement(identifyData, [$cover, $info]); that.updateElement(identifyData, [$icon, $info]);
} }
oml.bindEvent({ oml.bindEvent({

View file

@ -83,7 +83,7 @@ oml.ui.mainMenu = function() {
}, },
{}, {},
{ {
id: 'iconSubmenu', id: 'iconsSubmenu',
title: 'Icons', title: 'Icons',
items: [ items: [
{ {
@ -105,26 +105,27 @@ oml.ui.mainMenu = function() {
}, },
{}, {},
{ {
id: 'showfileinfo', id: 'showiconinfo',
title: 'Show File Info', title: 'Show Icon Info',
checked: ui.showFileInfo checked: ui.showIconInfo
}, },
{}, {},
{ {
group: 'fileinfo', group: 'iconinfo',
min: 1, min: 1,
max: 1, max: 1,
disabled: !ui.showFileInfo,
items: [ items: [
{ {
id: 'extension', id: 'extension',
title: Ox._('Show Extension'), title: Ox._('Show Extension'),
checked: ui.fileInfo == 'extension' checked: ui.iconInfo == 'extension',
disabled: !ui.showIconInfo
}, },
{ {
id: 'size', id: 'size',
title: Ox._('Show Size'), title: Ox._('Show Size'),
checked: ui.fileInfo == 'size' checked: ui.iconInfo == 'size',
disabled: !ui.showIconInfo
} }
] ]
} }
@ -283,10 +284,12 @@ oml.ui.mainMenu = function() {
? data.checked : data.checked[0].id; ? data.checked : data.checked[0].id;
if (id == 'icons') { if (id == 'icons') {
oml.UI.set({icons: value}); oml.UI.set({icons: value});
} else if (id == 'showfileinfo') { } else if (id == 'icons') {
oml.UI.set({showFileInfo: value}); oml.UI.set({icons: value});
} else if (id == 'fileinfo') { } else if (id == 'showiconinfo') {
oml.UI.set({fileInfo: value}); oml.UI.set({showIconInfo: value});
} else if (id == 'iconinfo') {
oml.UI.set({iconInfo: value});
} else if (id == 'sort') { } else if (id == 'sort') {
oml.UI.set({ oml.UI.set({
listSort: [{ listSort: [{
@ -512,6 +515,12 @@ oml.ui.mainMenu = function() {
that[action]('deletelist'); that[action]('deletelist');
*/ */
}, },
oml_iconinfo: function(data) {
// ...
},
oml_icons: function(data) {
that.checkItem('viewMenu_iconsSubmenu_' + data.value);
},
oml_item: function(data) { oml_item: function(data) {
if (!!data.value != !!data.previousValue) { if (!!data.value != !!data.previousValue) {
that[data.value ? 'disableItem' : 'enableItem']('showfilters'); that[data.value ? 'disableItem' : 'enableItem']('showfilters');
@ -533,6 +542,11 @@ oml.ui.mainMenu = function() {
oml_showfilters: function(data) { oml_showfilters: function(data) {
that.setItemTitle('showfilters', Ox._((data.value ? 'Hide' : 'Show') + ' Filters')); that.setItemTitle('showfilters', Ox._((data.value ? 'Hide' : 'Show') + ' Filters'));
}, },
oml_showiconinfo: function(data) {
var action = data.value ? 'enableItem' : 'disableItem';
that[action]('viewMenu_iconsSubmenu_extension');
that[action]('viewMenu_iconsSubmenu_size');
},
oml_showinfo: function(data) { oml_showinfo: function(data) {
that.setItemTitle('showinfo', Ox._((data.value ? 'Hide' : 'Show') + ' Info')); that.setItemTitle('showinfo', Ox._((data.value ? 'Hide' : 'Show') + ' Info'));
}, },

View file

@ -184,7 +184,12 @@
|| document.documentElement, || document.documentElement,
script = document.createElement('script'); script = document.createElement('script');
script.onload = function() { script.onload = function() {
Ox.load({UI: {theme: theme}}, callback); Ox.load({UI: {theme: theme}}, function() {
Ox.formatUpper = function(string) {
return string.toUpperCase();
};
callback();
});
}; };
script.src = oxjsPath + '/Ox.js?' + omlVersion; script.src = oxjsPath + '/Ox.js?' + omlVersion;
script.type = 'text/javascript'; script.type = 'text/javascript';

View file

@ -7,7 +7,7 @@ oml.ui.previewDialog = function() {
$image, $image,
$list = oml.$ui.list, $list = oml.$ui.list,
item = Ox.last($list.options('selected')), item = Ox.last($list.options('selected')),
coverRatio = $list.value(item, 'coverRatio') || oml.config.coverRatio, coverRatio = $list.value(item, 'coverRatio') || oml.config.iconRatio,
size = getSize(coverRatio), size = getSize(coverRatio),
that = Ox.Dialog({ that = Ox.Dialog({

View file

@ -133,6 +133,27 @@ oml.clickLink = function(e) {
} }
}; };
oml.createLinks = function($element) {
function isExternalLink(target) {
return target.hostname != document.location.hostname
|| Ox.startsWith(target.pathname, '/static');
}
$element.on({
click: function(e) {
var $target = $(e.target);
if ($target.is('a')) {
e.preventDefault();
if (isExternalLink(e.target)) {
oml.openLink(e.target.href);
} else {
oml.clickLink(e);
}
}
return false;
}
});
};
(function() { (function() {
oml.doHistory = function(action, items, targets, callback) { oml.doHistory = function(action, items, targets, callback) {
@ -713,7 +734,15 @@ oml.getEditTooltip = function(title) {
}()); }());
oml.getFileInfoColor = function(type, data) { oml.getFilterSizes = function() {
var ui = oml.user.ui;
return Ox.splitInt(
window.innerWidth - ui.showSidebar * ui.sidebarSize - 1,
5
);
};
oml.getIconInfoColor = function(type, data) {
return type == 'extension' ? ( return type == 'extension' ? (
data.extension == 'epub' ? [[32, 160, 32], [0, 128, 0], [128, 255, 128]] data.extension == 'epub' ? [[32, 160, 32], [0, 128, 0], [128, 255, 128]]
: data.extension == 'pdf' ? ( : data.extension == 'pdf' ? (
@ -728,14 +757,6 @@ oml.getFileInfoColor = function(type, data) {
: [[224, 32, 32], [192, 0, 0], [255, 192, 192]]; : [[224, 32, 32], [192, 0, 0], [255, 192, 192]];
}; };
oml.getFilterSizes = function() {
var ui = oml.user.ui;
return Ox.splitInt(
window.innerWidth - ui.showSidebar * ui.sidebarSize - 1,
5
);
};
oml.getInfoHeight = function() { oml.getInfoHeight = function() {
return Math.min( return Math.min(
oml.user.ui.sidebarSize, oml.user.ui.sidebarSize,
@ -909,8 +930,7 @@ oml.openLink = function(url) {
if (Ox.startsWith(url, 'mailto:')) { if (Ox.startsWith(url, 'mailto:')) {
window.open(url); window.open(url);
} else { } else {
//window.open('/url=' + encodeURIComponent(url), '_blank'); window.open('/url=' + encodeURIComponent(url), '_blank');
window.open(url, '_blank');
} }
}; };