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)) {