Implement progress bar while loading library data

This commit is contained in:
Kovid Goyal 2015-10-16 12:35:13 +05:30
parent ba95bf86b9
commit d2ba80ec41
6 changed files with 137 additions and 27 deletions

View File

@ -2,9 +2,24 @@
<html>
<head>
<title>calibre</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<script type="text/javascript" src="js/main.js"></script>
<meta charset="utf-8"/>
<script>window.interface_data_url = 'ajax/interface-data';</script>
<script type="text/javascript" src="static/main.js"></script>
<link rel="stylesheet" href="static/reset.css"></link>
</head>
<body>
<div id="page_load_progress">
<progress>
</progress>
<div>Loading library, please wait&hellip;<div>
<style type="text/css">
#page_load_progress {
position:relative;
top: 50px;
margin-left: auto; margin-right: auto;
text-align: center;
}
</style>
</div>
</body>
</html>

View File

@ -0,0 +1,74 @@
/*
* Reset CSS to suppress cross-browser differences
*/
html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code,
del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var,
b, i,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
margin:0;
padding:0;
border:0;
outline:0;
font-size:100%;
vertical-align:baseline;
background:transparent;
}
body {
line-height:1;
font-family: sans-serif;
}
article,aside,details,figcaption,figure,
footer,header,hgroup,menu,nav,section {
display:block;
}
nav ul {
list-style:none;
}
blockquote, q {
quotes:none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content:'';
content:none;
}
a {
margin:0;
padding:0;
font-size:100%;
vertical-align:baseline;
background:transparent;
}
table {
border-collapse:collapse;
border-spacing:0;
}
hr {
display:block;
height:1px;
border:0;
border-top:1px solid currentColor;
margin:1em 0;
padding:0;
}
input, select {
vertical-align:middle;
}

View File

@ -580,7 +580,6 @@ def interface_data(ctx, rd, library_id):
num = int(rd.query.get('num', 75))
except Exception:
raise HTTPNotFound('Invalid number of books: %r' % rd.query.get('num'))
last_modified = None
db = get_db(ctx, library_id)
with db.safe_read_lock:
ans['search_result'] = _search(ctx, rd, db, '', num, 0, ','.join(sorts), ','.join(orders))
@ -588,10 +587,7 @@ def interface_data(ctx, rd, library_id):
# ans['categories'] = ctx.get_categories(rd, db)
mdata = ans['metadata'] = {}
for book_id in ans['search_result']['book_ids']:
data, lm = book_to_json(ctx, rd, db, book_id)
last_modified = lm if last_modified is None else max(lm, last_modified)
data, last_modified = book_to_json(ctx, rd, db, book_id)
mdata[book_id] = data
if last_modified is not None:
rd.outheaders['Last-Modified'] = http_date(timestampfromdt(last_modified))
return ans

View File

@ -4,21 +4,9 @@
from __future__ import (unicode_literals, division, absolute_import,
print_function)
import errno
from calibre import sanitize_file_name2
from calibre.srv.errors import HTTPNotFound
from calibre.srv.routes import endpoint
@endpoint('', auth_required=False)
def index(ctx, rd):
return lopen(P('content-server/index.html'), 'rb')
@endpoint('/js/{which}', auth_required=False)
def js(ctx, rd, which):
try:
return lopen(P('content-server/' + sanitize_file_name2(which)), 'rb')
except EnvironmentError as e:
if e.errno == errno.ENOENT:
raise HTTPNotFound('No js with name: %r' % which)
raise

View File

@ -1,14 +1,36 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
def ajax(path, on_complete, on_progress=None, bypass_cache=True):
def ajax(path, on_complete, on_progress=None, bypass_cache=True, method='GET'):
xhr = XMLHttpRequest()
if bypass_cache:
path += ('&' if '?' in path else '?') + Date().getTime()
def progress_callback(ev):
if ev.lengthComputable:
on_progress(ev.loaded, ev.total, xhr)
elif ev.loaded:
ul = xhr.getResponseHeader('Calibre-Uncompressed-Length')
if ul:
try:
ul = int(ul)
except Exception:
return
on_progress(ev.loaded, ul)
def complete_callback(end_type, ev):
if end_type != 'load':
on_complete(end_type, xhr, ev)
return
if not (200 <= xhr.status < 300):
end_type = 'error'
on_complete(end_type, xhr, ev)
if on_progress:
xhr.addEventListener('progress', on_progress)
xhr.addEventListener('abort', def(ev): on_complete('abort', this, xhr);)
xhr.addEventListener('error', def(ev): on_complete('error', this, xhr);)
xhr.addEventListener('load', def(ev): on_complete('load', this, xhr);)
xhr.addEventListener('progress', progress_callback)
xhr.addEventListener('abort', def(ev): complete_callback('abort', xhr, ev);)
xhr.addEventListener('error', def(ev): complete_callback('error', xhr, ev);)
xhr.addEventListener('load', def(ev): complete_callback('load', xhr, ev);)
xhr.open(method, path)
return xhr

View File

@ -1,13 +1,28 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
from ajax import ajax
from elementmaker import E
from gettext import gettext as _
def create_page_load_progress_bar():
E.progress(id='library_load_bar')
def on_library_loaded(end_type, xhr, ev):
p = document.getElementById('page_load_progress')
p.parentNode.removeChild(p)
if end_type == 'load':
data = xhr.response
data
else:
document.body.appendChild(E.p(style="color:red", _(
'Failed to download library data, with status:') + str.format(' [{}] {}', xhr.status, xhr.statusText)
))
def on_library_load_progress(loaded, total):
p = document.querySelector('#page_load_progress > progress')
p.max = total
p.value = loaded
def on_document_loaded():
alert(11111111)
ajax(window.interface_data_url, on_library_loaded, on_library_load_progress).send()
# We wait for all page elements to load, since this is a single page app
# with a largely empty starting document, we can use this to preload any resources