/* COLUMNS */
var cmap = ['title', 'authors', 'rating', 'date', 'series'];
/* COLUMNS END */
var column_titles = {
'title' : 'Title',
'authors' : 'Author(s)',
'rating' : 'Rating',
'date' : 'Date',
'tags' : 'Tags',
'series' : 'Series'
};
String.prototype.format = function() {
var pattern = /\{\d+\}/g;
var args = arguments;
return this.replace(pattern, function(capture){ return args[capture.match(/\d+/)]; });
}
var last_search = '';
var last_sort = null;
var last_sort_order = null;
var last_start = 0;
var last_num = 20;
var total = 0;
var current_library_request = null;
////////////////////////////// GET BOOK LIST //////////////////////////////
var LIBRARY_FETCH_TIMEOUT = 10000; // milliseconds
function create_table_headers() {
var thead = $('table#book_list thead tr');
var titles = '';
for (i = 0; i < cmap.length; i++) {
titles += '
{0} ↑ | '
.format(column_titles[cmap[i]], cmap[i]);
}
thead.html(titles);
}
function format_url(format, id, title) {
return 'get/'+format.toLowerCase() + '/'+encodeURIComponent(title) + '_' + id+'.'+format.toLowerCase();
}
function render_book(book) {
// Render title cell
var title = '{0}'.format(book.attr("title")) + '
';
var id = book.attr("id");
var comments = $.trim(book.text()).replace(/\n\n/, '
');
var formats = new Array();
var size = (parseFloat(book.attr('size'))/(1024*1024)).toFixed(1);
var tags = book.attr('tags')
formats = book.attr("formats").split(",");
if (formats.length > 0) {
for (i=0; i < formats.length; i++) {
title += ''+formats[i]+', ';
}
title = title.slice(0, title.length-2);
title += ' ({0} MB) '.format(size);
}
if (tags) title += 'Tags=[{0}] '.format(tags);
custcols = book.attr("custcols").split(',')
for ( i = 0; i < custcols.length; i++) {
if (custcols[i].length > 0) {
vals = book.attr(custcols[i]).split(':#:', 2);
title += '{0}=[{1}] '.format(vals[0], vals[1]);
}
}
title += '
'.format(id);
title += ''.format(comments)
// Render authors cell
var _authors = new Array();
var authors = '';
_authors = book.attr('authors').split('|');
for (i = 0; i < _authors.length; i++) {
authors += jQuery.trim(_authors[i]).replace(/ /g, ' ')+'
';
}
if (authors) { authors = authors.slice(0, authors.length-6); }
// Render rating cell
var _rating = parseFloat(book.attr('rating'))/2.;
var rating = '';
for (i = 0; i < _rating; i++) { rating += '★'}
// Render date cell
var _date = Date.parseExact(book.attr('timestamp'), 'yyyy/MM/dd HH:mm:ss');
var date = _date.toString('d MMM yyyy').replace(/ /g, ' ');
// Render series cell
var series = book.attr("series")
if (series) {
series += ' [{0}]'.format(book.attr('series_index'));
}
var cells = {
'title' : title,
'authors' : authors,
'rating' : rating,
'date' : date,
'series' : series
};
var row = '';
for (i = 0; i < cmap.length; i++) {
row += '{1} | '.format(cmap[i], cells[cmap[i]]);
}
return '{1}
'.format(id, row);
}
function fetch_library_books(start, num, timeout, sort, order, search) {
// null, 0, false are False
data = {"start":start+'', "num":num+''};
if (sort) { data["sort"] = sort; }
if (search) { data["search"] = search; }
if (order) { data['order'] = order; }
last_num = num;
last_start = start;
last_search = search;
last_sort = sort;
last_sort_order = order;
if (current_library_request != null) {
current_library_request.abort();
current_library_request = null;
}
$('#cover_pane').css('visibility', 'hidden');
$('#loading').css('visibility', 'visible');
current_library_request = $.ajax({
type: "GET",
url: "xml",
data: data,
cache: false,
timeout: timeout, //milliseconds
dataType: "xml",
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert('Error: '+textStatus+'\n\n'+errorThrown);
},
success : function(xml, textStatus) {
var library = $(xml).find('library');
total = parseInt(library.attr('total'));
var num = parseInt(library.attr('num'));
var start = parseInt(library.attr('start'));
update_count_bar(start, num, total);
var display = '';
library.find('book').each( function() {
var book = $(this);
var row = render_book(book);
display += row+'\n\n';
});
$("#book_list tbody").html(display);
$("#book_list tbody tr").bind('mouseenter', function() {
var row = $(this);
$('#book_list tbody tr:even').css('background-color', '#eeeeee');
$('#book_list tbody tr:odd').css('background-color', 'white');
row.css('background-color', "#fff2a8");
row.bind('mouseleave', function(){
row.css('background-color', "white");
$('#book_list tbody tr:even').css('background-color', '#eeeeee');
row.unbind('mouseleave');
});
});
$("#book_list tbody tr").click(function(){
var row = $(this);
var cover = row.find('img').attr('src');
var collapsed = row.find('.comments').css('display') == 'none';
$("#book_list tbody tr * .comments").css('display', 'none');
$('#cover_pane').css('visibility', 'hidden');
if (collapsed) {
row.find('.comments').css('display', 'inherit');
$('#cover_pane img').attr('src', cover);
$('#cover_pane').css('visibility', 'visible');
}
});
layout();
$('#book_list tbody tr:even').css('background-color', '#eeeeee');
},
complete : function(XMLHttpRequest, textStatus) {
current_library_request = null;
document.getElementById('main').scrollTop = 0;
$('#loading').css('visibility', 'hidden');
}
});
}
////////////////////////////// COUNT BAR //////////////////////////////
function update_count_bar(start, num, total) {
var cb = $('#count_bar');
cb.find('#count').html('Books {0} to {1} of {2}'.format(start+1, start+num, total));
var left = cb.find('#left');
left.css('opacity', (start <= 0) ? 0.3 : 1);
var right = cb.find('#right');
right.css('opacity', (start + num >= total) ? 0.3 : 1);
}
function setup_count_bar() {
$('#count_bar * img:eq(0)').click(function(){
if (last_start > 0) {
fetch_library_books(0, last_num, LIBRARY_FETCH_TIMEOUT, last_sort, last_sort_order, last_search);
}
});
$('#count_bar * img:eq(1)').click(function(){
if (last_start > 0) {
var new_start = last_start - last_num;
if (new_start < 0) {
new_start = 0;
}
fetch_library_books(new_start, last_num, LIBRARY_FETCH_TIMEOUT, last_sort, last_sort_order, last_search);
}
});
$('#count_bar * img:eq(2)').click(function(){
if (last_start + last_num < total) {
var new_start = last_start + last_num;
fetch_library_books(new_start, last_num, LIBRARY_FETCH_TIMEOUT, last_sort, last_sort_order, last_search);
}
});
$('#count_bar * img:eq(3)').click(function(){
if (total - last_num > 0) {
fetch_library_books(total - last_num, last_num, LIBRARY_FETCH_TIMEOUT, last_sort, last_sort_order, last_search);
}
});
}
////////////////////////////// SEARCH /////////////////////////////////////////
function search() {
var search = $.trim($('#search_box * #s').val());
fetch_library_books(0, last_num, LIBRARY_FETCH_TIMEOUT,
last_sort, last_sort_order, search);
}
/////////////////////////// SORTING /////////////////////////////////////
function setup_sorting() {
$('table#book_list thead tr td').mouseover(function() {
this.style.backgroundColor = "#fff2a8";
});
$('table#book_list thead tr td').mouseout(function() {
this.style.backgroundColor = "transparent";
});
for (i = 0; i < cmap.length; i++) {
$('table#book_list span#{0}_sort'.format(cmap[i])).parent().click(function() {
var sort_indicator = $($(this).find('span'));
var cell = $(sort_indicator.parent());
var id = sort_indicator.attr("id");
var col = id.slice(0, id.indexOf("_"));
var order = 'ascending';
var html = '↑';
if (sort_indicator.html() == '↑') {
order = 'descending'; html = '↓';
}
sort_indicator.html(html);
$('#book_list * .sort_indicator').css('visibility', 'hidden');
sort_indicator.css('visibility', 'visible');
fetch_library_books(last_start, last_num, LIBRARY_FETCH_TIMEOUT, col, order, last_search);
});
}
}
///////////////////////// STARTUP ////////////////////////////////////////
function layout() {
var main = $('#main'); var cb = $('#count_bar');
main.css('height', ($(window).height() - main.offset().top - 20)+'px')
main.css('width', ($(window).width() - main.offset().left - 15)+'px')
cb.css('right', '20px');
cb.css('top', (main.offset().top - cb.height()-5)+'px');
$('#loading').css('height', ($(window).height()-20)+'px');
$('#loading').css('width', ($(window).width()-20)+'px');
var cover = $('#cover_pane');
var title = $('#book_list thead tr td')
cover.css('width', (main.width()-title.offset().left - title.width()-15)+'px')
cover.css('height', main.height()+'px')
cover.css('left', (title.offset().left+title.width())+'px');
cover.css('top', main.offset().top+'px');
}
$(function() {
// document is ready
create_table_headers();
// Setup widgets
setup_sorting();
setup_count_bar();
$('#search_box * #s').val('');
$(window).resize(layout);
$($('#book_list * span#date_sort').parent()).click();
});