diff --git a/static/js/infoView.js b/static/js/infoView.js
index faef75d..dd24d75 100644
--- a/static/js/infoView.js
+++ b/static/js/infoView.js
@@ -4,7 +4,7 @@ oml.ui.infoView = function(identifyData) {
var ui = oml.user.ui,
- arrayKeys = ['author', 'place', 'publisher', 'language'],
+ arrayKeys = ['author', 'place', 'publisher', 'language', 'categories'],
iconSize = identifyData ? 256 : ui.iconSize,
@@ -18,6 +18,8 @@ oml.ui.infoView = function(identifyData) {
{key: 'olid', url: 'https://openlibrary.org/books/{0}'}
],
+ separator = '; ',
+
that = Ox.Element()
.addClass('OxTextPage')
.css({overflowY: 'auto'})
@@ -73,6 +75,32 @@ oml.ui.infoView = function(identifyData) {
.appendTo(that);
}
+ function formatLight(string) {
+ return '' + string + '';
+ }
+
+ function formatKey(key) {
+ return ''
+ + Ox._(Ox.getObjectById(oml.config.itemKeys, key).title)
+ + ': ';
+ }
+
+ function formatValue(value, key) {
+ var isEditor = key == 'author' && (value || []).some(function(value) {
+ return Ox.endsWith(value, ' (Ed.)');
+ });
+ return value ? (Ox.isArray(value) ? value : [value]).map(function(value) {
+ if (key == 'date' && value) {
+ value = value.slice(0, 4);
+ }
+ return key && !identifyData ?
+ '' + (
+ key == 'author' ? value.replace(/ \(Ed\.\)$/, '') : value
+ ) + ''
+ : value;
+ }).join(separator) + (isEditor ? ' (Ed.)' : '') : '';
+ }
+
function getCSS(size, ratio) {
var width = Math.round(ratio >= 1 ? size : size * ratio),
height = Math.round(ratio <= 1 ? size : size / ratio),
@@ -103,27 +131,6 @@ oml.ui.infoView = function(identifyData) {
: '';
}
- function formatLight(string) {
- return '' + string + '';
- }
-
- function formatKey(key) {
- var item = Ox.getObjectById(oml.config.itemKeys, key);
- return ''
- + Ox._(Ox.toTitleCase(key)) + ': ';
- }
-
- function formatValue(value, key) {
- return value ? (Ox.isArray(value) ? value : [value]).map(function(value) {
- if (key == 'date' && value) {
- value = value.slice(0, 4);
- }
- return key && !identifyData ?
- '' + value + ''
- : value;
- }).join('; ') : '';
- }
-
function identify(data) {
oml.$ui.identifyDialog = oml.ui.identifyDialog(data).open();
}
@@ -133,6 +140,7 @@ oml.ui.infoView = function(identifyData) {
elements: [
Ox.Button({
disabled: data.mediastate != 'available',
+ style: 'squared',
title: Ox._('Identify Book...'),
width: 112
})
@@ -158,6 +166,7 @@ oml.ui.infoView = function(identifyData) {
max: 1,
min: 1,
overlap: 'left',
+ style: 'squared',
title: 'select',
tooltip: Ox._('Set Primary ID'),
type: 'image',
@@ -179,22 +188,24 @@ oml.ui.infoView = function(identifyData) {
: Ox.Button({
disabled: true,
overlap: 'left',
+ style: 'squared',
title: 'select',
type: 'image'
})
],
float: 'right'
})
- .css({marginTop: '16px'});
+ .css({marginTop: '8px'});
}
function renderOpenButton(data) {
return data.mediastate == 'available'
? Ox.Button({
+ style: 'squared',
title: Ox._('Open Folder'),
width: 128
})
- .css({marginTop: '16px'})
+ .css({marginTop: '8px'})
.bindEvent({
click: function() {
oml.api.openFolder({id: oml.user.ui.item});
@@ -240,6 +251,7 @@ oml.ui.infoView = function(identifyData) {
? Ox.FormElementGroup({
elements: [
Ox.Button({
+ style: 'squared',
title: Ox._('Download Book'),
width: 112
})
@@ -256,6 +268,7 @@ oml.ui.infoView = function(identifyData) {
disabled: !ui._lists,
items: getListItems(),
overlap: 'left',
+ style: 'squared',
title: 'select',
tooltip: Ox._('Download Book to a List'),
type: 'image'
@@ -280,6 +293,7 @@ oml.ui.infoView = function(identifyData) {
? Ox.FormElementGroup({
elements: [
Ox.Button({
+ style: 'squared',
title: Ox._('Transferring...'),
width: 112
})
@@ -290,6 +304,7 @@ oml.ui.infoView = function(identifyData) {
}),
Ox.Button({
overlap: 'left',
+ style: 'squared',
title: 'close',
tooltip: Ox._('Cancel Transfer'),
type: 'image'
@@ -307,6 +322,7 @@ oml.ui.infoView = function(identifyData) {
float: 'right'
})
: Ox.Button({
+ style: 'squared',
title: Ox._('Read Book'),
width: 128
})
@@ -318,9 +334,14 @@ oml.ui.infoView = function(identifyData) {
return $element;
}
- function splitValue(value) {
- return Ox.decodeHTMLEntities(value).split('; ').map(function(value) {
- return Ox.encodeHTMLEntities(value);
+ function splitValue(value, key) {
+ var isEditor = key == 'author'
+ && Ox.decodeHTMLEntities(value).split(separator).some(function(value) {
+ return Ox.endsWith(value, ' (Ed.)');
+ });
+ return Ox.decodeHTMLEntities(value).split(separator).map(function(value) {
+ return Ox.encodeHTMLEntities(value).replace(/ \(Ed\.\)/, '')
+ + (isEditor ? ' (Ed.)' : '');
});
}
@@ -455,7 +476,7 @@ oml.ui.infoView = function(identifyData) {
} else if ($element == $info) {
- // -------- Title
+ // -------- Title --------
$('
')
.css({
@@ -480,7 +501,7 @@ oml.ui.infoView = function(identifyData) {
)
.appendTo($info);
- // -------- Author
+ // -------- Author --------
$('
')
.css({
@@ -491,11 +512,11 @@ oml.ui.infoView = function(identifyData) {
clickLink: oml.clickLink,
editable: isEditable,
format: function(value) {
- return formatValue(splitValue(value), 'author');
+ return formatValue(splitValue(value, 'author'), 'author');
},
placeholder: formatLight(Ox._('Unknown Author')),
tooltip: isEditable ? oml.getEditTooltip() : '',
- value: data.author ? Ox.encodeHTMLEntities(data.author.join('; ')) : ''
+ value: Ox.encodeHTMLEntities((data.author || []).join(separator))
})
.css({
marginBottom: '-3px',
@@ -510,14 +531,14 @@ oml.ui.infoView = function(identifyData) {
)
.appendTo($info);
- // -------- Place, Publisher, Date
+ // -------- Publisher, Place, Date --------
$div = $('
')
.css({
marginTop: '4px',
})
.appendTo($info);
- ['place', 'publisher', 'date'].forEach(function(key, index) {
+ ['publisher', 'place', 'date'].forEach(function(key, index) {
if (index) {
$('
').html(', ').appendTo($div);
}
@@ -536,10 +557,11 @@ oml.ui.infoView = function(identifyData) {
},
placeholder: formatLight(Ox._('unknown')),
tooltip: isEditable ? oml.getEditTooltip() : '',
- value: data[key] ? Ox.encodeHTMLEntities(
+ value: Ox.encodeHTMLEntities(
Ox.contains(arrayKeys, key)
- ? data[key].join('; ') : data[key]
- ) : ''
+ ? (data[key] || []).join(separator)
+ : (data[key] || '')
+ )
})
.bindEvent({
submit: function(event) {
@@ -549,14 +571,14 @@ oml.ui.infoView = function(identifyData) {
.appendTo($div);
});
- // -------- Edition, Language, Pages
+ // -------- Series, Edition, Language, Pages --------
$div = $('')
.css({
marginTop: '4px',
})
.appendTo($info);
- ['edition', 'language', 'pages'].forEach(function(key, index) {
+ ['series', 'edition', 'language', 'pages'].forEach(function(key, index) {
if (index) {
$('
').html(', ').appendTo($div);
}
@@ -567,16 +589,19 @@ oml.ui.infoView = function(identifyData) {
clickLink: oml.clickLink,
editable: isEditable,
format: function(value) {
- return key == 'language'
- ? formatValue(splitValue(value), key)
- : value;
+ return formatValue(
+ Ox.contains(arrayKeys, key)
+ ? splitValue(value) : value,
+ key
+ );
},
placeholder: formatLight('unknown'),
tooltip: isEditable ? oml.getEditTooltip() : '',
- value: data[key] ? Ox.encodeHTMLEntities(
+ value: Ox.encodeHTMLEntities(
Ox.contains(arrayKeys, key)
- ? data[key].join('; ') : data[key]
- ) : ''
+ ? (data[key] || []).join(separator)
+ : (data[key] || '')
+ )
})
.bindEvent({
submit: function(event) {
@@ -586,74 +611,104 @@ oml.ui.infoView = function(identifyData) {
.appendTo($div);
});
- // -------- Primary ID
+ // -------- Categories --------
- if (data.primaryid) {
- $('')
+ if (data.categories || isEditable) {
+ $div = $('
')
.css({
marginTop: '4px',
})
- .html(
- '
' + Ox.getObjectById(oml.config.itemKeys, data.primaryid[0]).title
- + ': ' + data.primaryid[1]
- )
.appendTo($info);
- }
-
- // -------- Classification
-
- if (data.classification || isEditable) {
- $('
')
- .css({
- marginTop: '8px',
+ $('
')
+ .html(formatKey('categories'))
+ .appendTo($div);
+ Ox.EditableContent({
+ clickLink: oml.clickLink,
+ editable: isEditable,
+ format: function(value) {
+ return formatValue(splitValue(value), 'categories');
+ },
+ placeholder: formatLight(Ox._('unknown')),
+ tooltip: isEditable ? oml.getEditTooltip() : '',
+ value: Ox.encodeHTMLEntities((data.categories || []).join(separator))
})
- .append(
- Ox.EditableContent({
- clickLink: oml.clickLink,
- editable: isEditable,
- placeholder: formatLight('No Classification'),
- tooltip: isEditable ? oml.getEditTooltip() : '',
- value: data.classification ? Ox.encodeHTMLEntities(data.classification) : '',
- })
- .bindEvent({
- submit: function(event) {
- editMetadata('classification', Ox.decodeHTMLEntities(event.value));
- }
- })
- )
- .appendTo($info);
+ .bindEvent({
+ submit: function(event) {
+ editMetadata('categories', Ox.decodeHTMLEntities(event.value));
+ }
+ })
+ .appendTo($div);
}
- // -------- Description
+ // -------- ISBN --------
- if (data.description || isEditable) {
- $('')
+ if (data.isbn || isEditable) {
+ $div = $('
')
.css({
- marginTop: '8px',
- textAlign: 'justify'
- }).append(
- Ox.EditableContent({
- clickLink: oml.clickLink,
- editable: isEditable,
- format: function(value) {
- return value.replace(/\n/g, '
');
- },
- placeholder: formatLight('No Description'),
- tooltip: isEditable ? oml.getEditTooltip() : '',
- type: 'textarea',
- value: data.description ? Ox.encodeHTMLEntities(data.description) : ''
- })
- .bindEvent({
- submit: function(event) {
- editMetadata(
- 'description',
- Ox.decodeHTMLEntities(event.value).replace(/
/g, '\n')
- );
- }
- })
- ).appendTo($info);
+ marginTop: '4px',
+ })
+ .appendTo($info);
+ $('
')
+ .html(formatKey('isbn'))
+ .appendTo($div);
+ Ox.EditableContent({
+ editable: isEditable,
+ format: function(value) {
+ return (value ? [
+ Ox.formatISBN(value, 13),
+ Ox.formatISBN(value, 10)
+ ] : []).join(separator);
+ },
+ placeholder: formatLight(Ox._('unknown')),
+ tooltip: isEditable ? oml.getEditTooltip() : '',
+ value: data.isbn || ''
+ })
+ .bindEvent({
+ submit: function(event) {
+ var value = Ox.formatISBN(event.value, 13);
+ this.options({value: value});
+ editMetadata('isbn', value);
+ }
+ })
+ .appendTo($div);
}
+ // -------- Description, Table of Contents --------
+
+ ['description', 'tableofcontents'].forEach(function(key) {
+ if (data[key] || isEditable) {
+ $('')
+ .css({
+ marginTop: '8px',
+ textAlign: 'justify'
+ })
+ .append(
+ Ox.EditableContent({
+ clickLink: oml.clickLink,
+ editable: isEditable,
+ format: function(value) {
+ return value.replace(/\n/g, '
');
+ },
+ placeholder: formatLight(Ox._('No {0}', [
+ Ox.getObjectById(oml.config.itemKeys, key).title
+ ])),
+ tooltip: isEditable ? oml.getEditTooltip() : '',
+ type: 'textarea',
+ value: Ox.encodeHTMLEntities(data[key] || '')
+ })
+ .bindEvent({
+ submit: function(event) {
+ editMetadata(
+ key,
+ Ox.decodeHTMLEntities(event.value).replace(/
/g, '\n')
+ );
+ }
+ })
+ )
+ .appendTo($info);
+ }
+ });
+
$('
').css({height: '16px'}).appendTo($info);
oml.createLinks($info);
@@ -675,6 +730,8 @@ oml.ui.infoView = function(identifyData) {
)
.appendTo($data);
+ renderIdentifyButton(data).appendTo($data);
+
['accessed', 'modified', 'added', 'created'].forEach(function(id) {
var title;
if (data[id]) {
@@ -692,36 +749,6 @@ oml.ui.infoView = function(identifyData) {
}
});
- renderIdentifyButton(data).appendTo($data);
-
- ids.forEach(function(id, index) {
- var title;
- if (data[id.key] && !Ox.isEmpty(data[id.key])) {
- title = Ox.getObjectById(oml.config.itemKeys, id.key).title;
- $('
')
- .css({
- marginTop: (index == 0 ? 10 : 6) + 'px',
- fontWeight: 'bold'
- })
- .text(title)
- .appendTo($data);
- Ox.makeArray(data[id.key]/*FIXME!*/).forEach(function(value) {
- var isPrimary = data.primaryid && data.primaryid[0] == id.key
- && data.primaryid[1] == value;
- value = Ox.encodeHTMLEntities(value);
- Ox.Element({
- tooltip: isPrimary ? 'Primary ID' : ''
- })
- .html(
- '
' + value + ''
- + (isPrimary ? ' (*)' : '')
- )
- .appendTo($data);
- });
- }
- });
-
renderOpenButton(data).appendTo($data);
$('
').css({height: '16px'}).appendTo($data);
@@ -733,11 +760,11 @@ oml.ui.infoView = function(identifyData) {
function editMetadata(key, value) {
if (value != data[key]) {
var edit = {id: data.id};
- if (Ox.contains(arrayKeys, key)) {
- edit[key] = value ? value.split('; ') : [];
- } else {
- edit[key] = value;
- }
+ edit[key] = key == 'author'
+ ? splitValue(value || [], 'author')
+ : Ox.contains(arrayKeys, key)
+ ? (value || '').split(separator)
+ : value;
oml.api.edit(edit, function(result) {
Ox.Request.clearCache();
if (Ox.contains(['title', 'author', 'description'], key)) {