')
.css({
width: width + 'px',
height: Math.round(size / 12.8) + 'px',
@@ -38,7 +39,7 @@ oml.ui.gridView = function() {
WebkitTransform: 'rotate(45deg)'
})
.html(
- ui.fileInfo == 'extension'
+ ui.iconInfo == 'extension'
? data.extension.toUpperCase()
: Ox.formatValue(data.size, 'B')
) : null,
@@ -46,7 +47,7 @@ oml.ui.gridView = function() {
id: data.id,
info: info,
title: data.title,
- url: '/' + data.id + '/cover128.jpg',
+ url: '/' + data.id + '/' + ui.icons + '128.jpg',
width: width
};
},
@@ -56,13 +57,24 @@ oml.ui.gridView = function() {
}), callback);
},
keys: [
- 'author', 'coverRatio', 'extension', 'id',
- 'mediastate', 'size', 'textsize', 'title'
+ 'author', 'coverRatio', 'extension', 'id', 'mediastate',
+ 'previewRatio', 'size', 'textsize', 'title'
],
selected: ui.listSelection,
size: 128,
sort: ui.listSort,
unique: 'id'
+ })
+ .bindEvent({
+ oml_iconinfo: function() {
+ that.reloadList(true);
+ },
+ oml_icons: function() {
+ that.reloadList(true);
+ },
+ oml_showiconinfo: function() {
+ that.reloadList(true);
+ }
});
return that;
diff --git a/static/js/identifyDialog.js b/static/js/identifyDialog.js
index d517dfc..3c20347 100644
--- a/static/js/identifyDialog.js
+++ b/static/js/identifyDialog.js
@@ -4,8 +4,8 @@ oml.ui.identifyDialog = function(data) {
var ui = oml.user.ui,
- ids = [
- 'isbn10', 'isbn13', 'asin', 'lccn', 'oclc', 'olid'
+ lookupItems = [
+ 'isbn', 'asin', 'lccn', 'oclc', 'olid'
].map(function(id) {
return {
id: id,
@@ -13,48 +13,113 @@ oml.ui.identifyDialog = function(data) {
};
}),
- keys = [
- '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
- };
- }),
+ selected = data.primaryid ? 'lookup' : 'find',
- 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)
: Ox.Element(),
- $idPanel = Ox.SplitPanel({
+ $lookupPanel = Ox.SplitPanel({
elements: [
- {element: Ox.Element().append($idForm), size: 96},
- {element: $idPreview}
+ {element: $lookupForm, size: 48},
+ {element: $lookupPreview}
],
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: [
- {element: $titleForm, size: 96},
- {element: renderResults()}
+ {element: $findForm, size: 48},
+ {element: renderResults([])}
],
orientation: 'vertical'
}),
@@ -63,8 +128,8 @@ oml.ui.identifyDialog = function(data) {
$buttons = Ox.ButtonGroup({
buttons: [
- {id: 'id', title: Ox._('Look Up by ID')},
- {id: 'title', title: Ox._('Find by Title')}
+ {id: 'lookup', title: Ox._('Look Up by ID')},
+ {id: 'find', title: Ox._('Find by Title')}
],
selectable: true,
value: selected
@@ -78,14 +143,17 @@ oml.ui.identifyDialog = function(data) {
change: function(data) {
selected = data.value;
$innerPanel.options({selected: selected});
+ $updateButton.options({
+ disabled: selected == 'find' && !$findList
+ });
}
})
.appendTo($bar),
$innerPanel = Ox.SlidePanel({
elements: [
- {id: 'id', element: $idPanel},
- {id: 'title', element: $titlePanel}
+ {id: 'lookup', element: $lookupPanel},
+ {id: 'find', element: $findPanel}
],
orientation: 'horizontal',
selected: selected,
@@ -100,43 +168,89 @@ oml.ui.identifyDialog = function(data) {
orientation: 'vertical'
}),
- that = Ox.Dialog({
- buttons: [
- Ox.Button({
- id: 'dontupdate',
- title: Ox._('No, Don\'t Update')
- })
- .bindEvent({
- click: function() {
- that.close();
+ $metadataSelect = Ox.Select({
+ items: [
+ {id: 'original', title: Ox._('Show Original Metadata')},
+ {id: 'edited', title: Ox._('Show Edited Metadata')}
+ ],
+ max: 1,
+ min: 1,
+ value: 'edited',
+ 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',
- title: Ox._('Yes, Update')
- })
- .bindEvent({
- click: function() {
- Ox.print('$$$', idValue);
- var edit = Ox.extend(
- {id: data.id},
- $innerPanel.options('selected') == 'id'
- ? idValue || {mainid: ''}
- : titleValue
+ }
+ }),
+
+ $dontUpdateButton = Ox.Button({
+ id: 'dontupdate',
+ title: Ox._('No, Don\'t Update')
+ })
+ .bindEvent({
+ click: function() {
+ that.close();
+ }
+ }),
+
+ $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();
- Ox.print('VALUE SENT:', edit)
- oml.api.edit(edit, function(result) {
+ }
+ that.options({content: Ox.LoadingScreen().start()});
+ that.disableButtons();
+ 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();
Ox.Request.clearCache('find');
oml.$ui.browser.reloadList(true);
Ox.Request.clearCache(data.id);
oml.$ui.infoView.updateElement(data.id);
});
- }
- })
+ });
+ }
+ }),
+
+ that = Ox.Dialog({
+ buttons: [
+ $dontUpdateButton,
+ $updateButton
],
closeButton: true,
content: $outerPanel,
@@ -147,379 +261,126 @@ oml.ui.identifyDialog = function(data) {
width: 768
});
+ $($metadataSelect.find('.OxButton')[0]).css({margin: 0});
+ $metadataSelect.appendTo($(that.find('.OxBar')[2]));
+
function disableButtons() {
- Ox.forEach(selected == 'id' ? $idButtons : $titleButtons, function($button) {
- $button.options({disabled: true});
+ $lookupSelect.options('items').forEach(function(item) {
+ $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();
- $titlePanel.replaceElement(1, Ox.LoadingScreen().start());
- oml.api.findMetadata(data, function(result) {
+ $findPanel.replaceElement(1, Ox.LoadingScreen().start());
+ oml.api.findMetadata({
+ query: $findInput.value()
+ }, function(result) {
var items = result.data.items.map(function(item, index) {
- return Ox.extend({index: (index + 1).toString()}, item);
- });
- updateTitleButtons();
- $titlePanel.replaceElement(1, renderResults(items));
+ return Ox.extend({index: index.toString()}, item);
+ });
+ enableButtons();
+ $updateButton.options({disabled: !items.length});
+ $findPanel.replaceElement(1, renderResults(items));
});
}
- function getMetadata(key, value) {
+ function lookupMetadata() {
disableButtons();
- $idPanel.replaceElement(1, Ox.LoadingScreen().start());
- oml.api.getMetadata(Ox.extend({}, key, value), function(result) {
- $idForm = renderIdForm(result.data);
- $idPreview = Ox.isEmpty(data) ? Ox.Element() : oml.ui.infoView(result.data);
- $idPanel
- .replaceElement(0, $idForm)
- .replaceElement(1, $idPreview);
+ $lookupPanel.replaceElement(1, Ox.LoadingScreen().start());
+ oml.api.getMetadata(Ox.extend(
+ {includeEdits: $metadataSelect.value() == 'edited'},
+ $lookupSelect.value(),
+ $lookupInput.value()
+ ), function(result) {
+ 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) {
- var $list = Ox.TableList({
- columns: [
- {
+ var $resultsPanel;
+ if (items.length) {
+ $findList = Ox.TableList({
+ columns: [{
format: function(value, data) {
- return value
- ? '
' + Ox.getObjectById(ids, value).title
- + ': ' + data[data.mainid]
- : '
No ID'
+ return '
' + Ox.getObjectById(
+ lookupItems, data.primaryid[0]
+ ).title + ': ' + data.primaryid[1]
},
- id: 'mainid',
+ id: 'index',
visible: true,
width: 192 - Ox.UI.SCROLLBAR_SIZE
- }
- ],
- items: [{
- 'index': '0',
- 'mainid': ''
- }].concat(items || []),
- keys: ['mainid', 'isbn10', 'isbn13'],
- min: 1,
- max: 1,
- scrollbarVisible: true,
- sort: [{key: 'index', operator: '+'}],
- unique: 'index'
- })
- .bindEvent({
- select: function(data) {
- var index = data.ids[0],
- mainid = $list.value(index, 'mainid');
- if (!mainid) {
- titleValue = {};
- keys.forEach(function(key) {
- titleValue[key.id] = titleInputValue(key.id);
+ }],
+ items: items,
+ keys: ['primaryid'].concat(lookupItems.map(function(item) {
+ return item.id;
+ })),
+ min: 1,
+ max: 1,
+ scrollbarVisible: true,
+ selected: ['0'],
+ sort: [{key: 'index', operator: '+'}],
+ unique: 'index'
+ })
+ .bindEvent({
+ select: function(data) {
+ var index = data.ids[0],
+ primaryId = $findList.value(index, 'primaryid');
+ Ox.print('EEEE', index, primaryId);
+ disableButtons();
+ $resultsPanel.replaceElement(1, Ox.LoadingScreen().start());
+ oml.api.getMetadata(Ox.extend(
+ {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});
- }
- });
}
- }
- }),
- $results = Ox.SplitPanel({
+ }),
+ $resultsPanel = Ox.SplitPanel({
elements: [
- {element: $list, size: 192},
+ {element: $findList || Ox.Element(), size: 192},
{element: Ox.Element()}
],
orientation: 'horizontal'
});
- return $results;
- }
-
- 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(', ') : [];
- }
+ setTimeout(function() {
+ $findList.triggerEvent('select', {ids: ['0']});
+ });
} else {
- $input.value(
- key == 'author' ? (value || []).join(', ') : value
- );
+ $findList = void 0;
+ $resultsPanel = Ox.Element();
}
- return value;
- }
-
- 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 $resultsPanel;
}
return that;
diff --git a/static/js/importExportDialog.js b/static/js/importExportDialog.js
index f951431..5597b6e 100644
--- a/static/js/importExportDialog.js
+++ b/static/js/importExportDialog.js
@@ -260,8 +260,8 @@ oml.ui.importExportDialog = function(selected) {
Ox.Select({
id: 'mode',
items: [
- {id: 'add', title: Ox._('Add (keep files in destination path)')},
- {id: 'replace', title: Ox._('Replace (delete files from destination path)')}
+ {id: 'add', title: Ox._('Add (keep all exisiting files in destination path)')},
+ {id: 'replace', title: Ox._('Replace (delete all existing files from destination path)')}
],
label: Ox._('Export Mode'),
labelWidth: 128,
diff --git a/static/js/infoView.js b/static/js/infoView.js
index 1d27e57..4c2a241 100644
--- a/static/js/infoView.js
+++ b/static/js/infoView.js
@@ -4,14 +4,17 @@ oml.ui.infoView = function(identifyData) {
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()
.addClass('OxTextPage')
.css({overflowY: 'auto'})
.bindEvent({
+ oml_icons: function() {
+ that.updateElement(ui.item, [$icon])
+ },
oml_item: function() {
if (ui.item) {
that.updateElement(ui.item);
@@ -24,12 +27,12 @@ oml.ui.infoView = function(identifyData) {
}
}),
- $cover = Ox.Element()
+ $icon = Ox.Element()
.css({
position: 'absolute',
left: '16px',
top: '16px',
- width: css.cover.width
+ width: css.icon.width
})
.appendTo(that),
@@ -41,7 +44,7 @@ oml.ui.infoView = function(identifyData) {
right: !identifyData ? '176px' : 16 + Ox.UI.SCROLLBAR_SIZE + 'px',
top: '16px'
})
- [coverSize == 512 ? 'hide' : 'show']()
+ [iconSize == 512 ? 'hide' : 'show']()
.appendTo(that),
$data,
@@ -65,7 +68,7 @@ oml.ui.infoView = function(identifyData) {
height = Math.round(ratio <= 1 ? size : size / ratio),
left = size == 256 ? Math.floor((size - width) / 2) : 0;
return {
- cover: {
+ icon: {
width: size + 'px'
},
info: {
@@ -82,34 +85,99 @@ oml.ui.infoView = function(identifyData) {
};
}
- function getImageSize(size, ratio) {
- var width = Math.round(ratio >= 1 ? size : size * ratio),
- height = Math.round(ratio <= 1 ? size : size / ratio),
- left = Math.floor((size - width) / 2);
- return {width: width, height: height, left: left};
+ function getIconTooltip() {
+ return !identifyData
+ ? 'Click to see ' + (ui.iconSize == 256 ? 'large' : 'small')
+ + ' ' + ui.icons + ', doubleclick to see '
+ + (ui.icons == 'cover' ? 'preview' : 'cover')
+ : '';
}
- function formatLight(str) {
- return '
' + str + '';
+ function formatLight(string) {
+ return '
' + string + '';
}
function formatKey(key) {
var item = Ox.getObjectById(oml.config.itemKeys, key);
return '
'
- + Ox._(Ox.toTitleCase(key)) + ': ';
+ + Ox._(Ox.toTitleCase(key)) + ': ';
}
- function formatValue(value, key, join) {
- value = Ox.encodeHTMLEntities(value);
+ function formatValue(value, key) {
return value ? (Ox.isArray(value) ? value : [value]).map(function(value) {
return key && !identifyData ?
- '
' + value + ''
+ '
' + value + ''
: value;
- }).join(join || ', ') : '';
+ }).join('; ') : '';
}
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: '
' + Ox.getObjectById(
+ oml.config.itemKeys, key
+ ).title + ': ' + value
+ };
+ });
+ })).concat([
+ {id: '', title: '
No ID'}
+ ]),
+ 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) {
@@ -166,7 +234,7 @@ oml.ui.infoView = function(identifyData) {
disabled: !ui._lists,
items: getListItems(),
overlap: 'left',
- title: 'list',
+ title: 'select',
tooltip: Ox._('Download Book to a List'),
type: 'image'
})
@@ -230,18 +298,19 @@ oml.ui.infoView = function(identifyData) {
function toggleCoverSize(ratio) {
var css;
- coverSize = coverSize == 256 ? 512 : 256,
- css = getCSS(coverSize, ratio);
- //$cover.animate(css.cover, 250);
+ iconSize = iconSize == 256 ? 512 : 256,
+ css = getCSS(iconSize, ratio);
+ //$icon.animate(css.icon, 250);
+ Ox.print('ANIMATE,', css)
$info.animate(css.info, 250);
$image.animate(css.image, 250);
$reflectionImage.animate(css.image, 250);
$reflection.animate(css.reflection, 250);
- oml.UI.set({coverSize: coverSize});
+ oml.UI.set({iconSize: iconSize});
}
function updateCover(ratio) {
- var css = getCSS(coverSize, ratio);
+ var css = getCSS(iconSize, ratio);
$image.css(css.image).show();
$reflectionImage.css(css.image);
$reflection.css(css.reflection).show();
@@ -254,7 +323,7 @@ oml.ui.infoView = function(identifyData) {
$elements = $elements
? Ox.makeArray($elements)
- : [$cover, $info, $data];
+ : [$icon, $info, $data];
(data ? Ox.noop : oml.api.get)({
id: id,
@@ -271,24 +340,27 @@ oml.ui.infoView = function(identifyData) {
Ox.print('BOOK DATA', data)
- var $mediaButton,
- isEditable = !data.mainid && data.mediastate == 'available',
+ var $div,
+ isEditable = data.mediastate == 'available' && !identifyData,
src = !identifyData
- ? '/' + data.id + '/cover512.jpg?' + data.modified
+ ? '/' + data.id + '/' + ui.icons + '512.jpg?' + data.modified
: data.cover,
- ratio = data.coverRatio || oml.config.coverRatio,
- size = coverSize,
+ ratio = (
+ ui.icons == 'cover' || identifyData
+ ? data.coverRatio : data.previewRatio
+ ) || oml.config.iconRatio,
+ size = iconSize,
reflectionSize = Math.round(size / 2);
$elements.forEach(function($element) {
$element.empty();
- if ($element == $cover) {
+ if ($element == $icon) {
$image = Ox.Element({
element: '
',
- tooltip: '' // TODO
+ tooltip: getIconTooltip()
})
.on({
error: function() {
@@ -312,13 +384,21 @@ oml.ui.infoView = function(identifyData) {
})
.hide()
.bindEvent({
+ doubleclick: function() {
+ if (!identifyData) {
+ oml.UI.set({
+ icons: ui.icons == 'cover'
+ ? 'preview' : 'cover'
+ });
+ }
+ },
singleclick: function() {
if (!identifyData) {
toggleCoverSize(ratio);
}
}
})
- .appendTo($cover);
+ .appendTo($icon);
$reflection = $('
')
.addClass('OxReflection')
@@ -329,7 +409,7 @@ oml.ui.infoView = function(identifyData) {
overflow: 'hidden'
})
.hide()
- .appendTo($cover);
+ .appendTo($icon);
$reflectionImage = $('
')
.attr({src: src})
@@ -348,58 +428,130 @@ oml.ui.infoView = function(identifyData) {
} else if ($element == $info) {
+ // -------- Title
+
$('
')
.css({
- marginTop: '-2px',
- fontSize: '13px',
- fontWeight: 'bold'
+ marginTop: '-2px'
})
- .html(
- data.title ? Ox.encodeHTMLEntities(data.title)
- : '
'
- + Ox._('No Title')
- + ''
+ .append(
+ Ox.EditableContent({
+ clickLink: oml.clickLink,
+ editable: isEditable,
+ tooltip: isEditable ? oml.getEditTooltip() : '',
+ value: data.title || 'No Title'
+ })
+ .css({
+ fontWeight: 'bold',
+ fontSize: '13px'
+ })
+ .bindEvent({
+ submit: function(event) {
+ editMetadata('title', event.value);
+ }
+ })
)
.appendTo($info);
- if (data.author) {
- $('
')
- .css({
- marginTop: '4px',
- fontSize: '13px',
- fontWeight: 'bold'
- })
- .html(formatValue(data.author, 'author'))
- .appendTo($info);
- }
+ // -------- Author
- if (data.place || data.publisher || data.date) {
- $('
')
- .css({
- marginTop: '8px'
- })
- .html(
- (formatValue(data.place, 'place', ' ; '))
- + (data.place && (data.publisher || data.date) ? ' : ' : '')
- + (formatValue(data.publisher, 'publisher'))
- + (data.publisher && data.date ? ', ' : '')
- + (data.date || '')
- )
- .appendTo($info);
- }
+ $('
')
+ .css({
+ marginTop: '2px'
+ })
+ .append(
+ Ox.EditableContent({
+ clickLink: oml.clickLink,
+ editable: isEditable,
+ format: function(value) {
+ return formatValue(value.split('; '), 'author');
+ },
+ placeholder: formatLight(Ox._('Unknown Author')),
+ 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) {
- $('
')
- .css({
- marginTop: '8px'
+ // -------- Place, Publisher, Date
+
+ $div = $('
')
+ .css({
+ marginTop: '4px',
+ })
+ .appendTo($info);
+ ['place', 'publisher', 'date'].forEach(function(key, index) {
+ if (index) {
+ $('
').html(', ').appendTo($div);
+ }
+ $('')
+ .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(
- (Ox.encodeHTMLEntities(data.edition || ''))
- + (data.edition && data.language ? '; ' : '')
- + (formatValue(data.language, 'language'))
- )
- .appendTo($info);
- }
+ .bindEvent({
+ submit: function(event) {
+ editMetadata(key, event.value);
+ }
+ })
+ .appendTo($div);
+ });
+
+ // -------- Edition, Language, Pages
+
+ $div = $('')
+ .css({
+ marginTop: '4px',
+ })
+ .appendTo($info);
+ ['edition', 'language', 'pages'].forEach(function(key, index) {
+ if (index) {
+ $('
').html(', ').appendTo($div);
+ }
+ $('')
+ .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) {
$('')
@@ -413,6 +565,8 @@ oml.ui.infoView = function(identifyData) {
.appendTo($info);
}
+ // -------- Description
+
if (data.description) {
$('
')
.css({
@@ -427,10 +581,11 @@ oml.ui.infoView = function(identifyData) {
$('
').css({height: '16px'}).appendTo($info);
+ oml.createLinks($info);
+
} else if ($element == $data) {
- $mediaButton = renderMediaButton(data)
- .appendTo($data);
+ renderMediaButton(data).appendTo($data);
$('
')
.addClass('OxSelectable')
@@ -439,7 +594,7 @@ oml.ui.infoView = function(identifyData) {
})
.text(
[
- (data.extension || '???').toUpperCase(), // FIXME
+ data.extension.toUpperCase(),
Ox.formatValue(data.size, 'B')
].join(', ')
)
@@ -462,24 +617,13 @@ oml.ui.infoView = function(identifyData) {
}
});
- Ox.Button({
- disabled: data.mediastate != 'available',
- title: Ox._('Identify Book...'),
- width: 128
- })
- .css({marginTop: '16px'})
- .bindEvent({
- click: function() {
- identify(data);
- }
- })
- .appendTo($data);
+ renderIdentifyButton(data).appendTo($data);
[
- 'isbn10', 'isbn13', 'asin', 'lccn', 'oclc', 'olid'
+ 'isbn', 'asin', 'lccn', 'oclc', 'olid'
].forEach(function(id, index) {
var title;
- if (data[id]) {
+ if (data[id] && !Ox.isEmpty(data[id])) {
title = Ox.getObjectById(oml.config.itemKeys, id).title;
$('
')
.css({
@@ -488,11 +632,19 @@ oml.ui.infoView = function(identifyData) {
})
.text(title)
.appendTo($data);
- Ox.EditableContent({
- editable: false,
- value: data[id]
- })
- .appendTo($data);
+ Ox.makeArray(data[id]/*FIXME!*/).forEach(function(value) {
+ var isPrimary = data.primaryid[0] == id
+ && data.primaryid[1] == value;
+ Ox.Element({
+ 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) {
- var edit;
- Ox.print('EM', key, 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) {
- Ox.Request.clearCache('find');
- oml.$ui.browser.reloadList();
- //that.updateElement(result.data, $info);
+ oml.$ui.browser.value(
+ result.data.id, key, result.data[key]
+ );
});
}
}
@@ -523,7 +678,7 @@ oml.ui.infoView = function(identifyData) {
if (!identifyData) {
ui.item && that.updateElement(ui.item);
} else {
- that.updateElement(identifyData, [$cover, $info]);
+ that.updateElement(identifyData, [$icon, $info]);
}
oml.bindEvent({
diff --git a/static/js/mainMenu.js b/static/js/mainMenu.js
index 6db65a5..03c3b65 100644
--- a/static/js/mainMenu.js
+++ b/static/js/mainMenu.js
@@ -83,7 +83,7 @@ oml.ui.mainMenu = function() {
},
{},
{
- id: 'iconSubmenu',
+ id: 'iconsSubmenu',
title: 'Icons',
items: [
{
@@ -105,26 +105,27 @@ oml.ui.mainMenu = function() {
},
{},
{
- id: 'showfileinfo',
- title: 'Show File Info',
- checked: ui.showFileInfo
+ id: 'showiconinfo',
+ title: 'Show Icon Info',
+ checked: ui.showIconInfo
},
{},
{
- group: 'fileinfo',
+ group: 'iconinfo',
min: 1,
max: 1,
- disabled: !ui.showFileInfo,
items: [
{
id: 'extension',
title: Ox._('Show Extension'),
- checked: ui.fileInfo == 'extension'
+ checked: ui.iconInfo == 'extension',
+ disabled: !ui.showIconInfo
},
{
id: '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;
if (id == 'icons') {
oml.UI.set({icons: value});
- } else if (id == 'showfileinfo') {
- oml.UI.set({showFileInfo: value});
- } else if (id == 'fileinfo') {
- oml.UI.set({fileInfo: value});
+ } else if (id == 'icons') {
+ oml.UI.set({icons: value});
+ } else if (id == 'showiconinfo') {
+ oml.UI.set({showIconInfo: value});
+ } else if (id == 'iconinfo') {
+ oml.UI.set({iconInfo: value});
} else if (id == 'sort') {
oml.UI.set({
listSort: [{
@@ -512,6 +515,12 @@ oml.ui.mainMenu = function() {
that[action]('deletelist');
*/
},
+ oml_iconinfo: function(data) {
+ // ...
+ },
+ oml_icons: function(data) {
+ that.checkItem('viewMenu_iconsSubmenu_' + data.value);
+ },
oml_item: function(data) {
if (!!data.value != !!data.previousValue) {
that[data.value ? 'disableItem' : 'enableItem']('showfilters');
@@ -533,6 +542,11 @@ oml.ui.mainMenu = function() {
oml_showfilters: function(data) {
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) {
that.setItemTitle('showinfo', Ox._((data.value ? 'Hide' : 'Show') + ' Info'));
},
diff --git a/static/js/oml.js b/static/js/oml.js
index 726913a..d141cae 100644
--- a/static/js/oml.js
+++ b/static/js/oml.js
@@ -184,7 +184,12 @@
|| document.documentElement,
script = document.createElement('script');
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.type = 'text/javascript';
diff --git a/static/js/previewDialog.js b/static/js/previewDialog.js
index 7f66d23..ae58766 100644
--- a/static/js/previewDialog.js
+++ b/static/js/previewDialog.js
@@ -7,7 +7,7 @@ oml.ui.previewDialog = function() {
$image,
$list = oml.$ui.list,
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),
that = Ox.Dialog({
diff --git a/static/js/utils.js b/static/js/utils.js
index e8fc2c8..1d5f604 100644
--- a/static/js/utils.js
+++ b/static/js/utils.js
@@ -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() {
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' ? (
data.extension == 'epub' ? [[32, 160, 32], [0, 128, 0], [128, 255, 128]]
: data.extension == 'pdf' ? (
@@ -728,14 +757,6 @@ oml.getFileInfoColor = function(type, data) {
: [[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() {
return Math.min(
oml.user.ui.sidebarSize,
@@ -909,8 +930,7 @@ oml.openLink = function(url) {
if (Ox.startsWith(url, 'mailto:')) {
window.open(url);
} else {
- //window.open('/url=' + encodeURIComponent(url), '_blank');
- window.open(url, '_blank');
+ window.open('/url=' + encodeURIComponent(url), '_blank');
}
};