mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Implement progress bar while loading library data
This commit is contained in:
parent
ba95bf86b9
commit
d2ba80ec41
@ -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…<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>
|
||||
|
74
resources/content-server/reset.css
Normal file
74
resources/content-server/reset.css
Normal 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;
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user