mirror of
https://github.com/janeczku/calibre-web
synced 2025-06-10 10:24:10 +00:00
Refactor epub reader progress calculation
The code in epub-progress.js was causing the epub file to be loaded twice over the network, because it created a second instance of the epub.js library. I moved all the progress percentage display code into epub.js. Only the locationchange polyfill code was left in the separate file, renamed to locationchange-polyfill.js. I rewrote the percentage progress code to use epub.js events, giving more succinct and readable code. Also, I added localStorage caching of the epub location calculations, required for displaying percentage progress, which can take up to 60-90 seconds to calculate on longer ebooks. This localStorage caching approach is recommended by epub.js in the `locations.html` example in their repo. Signed-off-by: Ross Williams <ross@ross-williams.net>
This commit is contained in:
parent
efc7ce31d2
commit
22a93a28e2
@ -831,4 +831,5 @@ input:-moz-placeholder { color: #454545; }
|
|||||||
bottom: 4rem;
|
bottom: 4rem;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
/**
|
|
||||||
* waits until queue is finished, meaning the book is done loading
|
|
||||||
* @param callback
|
|
||||||
*/
|
|
||||||
function qFinished(callback){
|
|
||||||
let timeout=setInterval(()=>{
|
|
||||||
if(reader.rendition.q.running===undefined)
|
|
||||||
clearInterval(timeout);
|
|
||||||
callback();
|
|
||||||
},300
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateProgress(){
|
|
||||||
let data=reader.rendition.location.end;
|
|
||||||
return Math.round(epub.locations.percentageFromCfi(data.cfi)*100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// register new event emitter locationchange that fires on urlchange
|
|
||||||
// source: https://stackoverflow.com/a/52809105/21941129
|
|
||||||
(() => {
|
|
||||||
let oldPushState = history.pushState;
|
|
||||||
history.pushState = function pushState() {
|
|
||||||
let ret = oldPushState.apply(this, arguments);
|
|
||||||
window.dispatchEvent(new Event('locationchange'));
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
let oldReplaceState = history.replaceState;
|
|
||||||
history.replaceState = function replaceState() {
|
|
||||||
let ret = oldReplaceState.apply(this, arguments);
|
|
||||||
window.dispatchEvent(new Event('locationchange'));
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener('popstate', () => {
|
|
||||||
window.dispatchEvent(new Event('locationchange'));
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
window.addEventListener('locationchange',()=>{
|
|
||||||
let newPos=calculateProgress();
|
|
||||||
progressDiv.textContent=newPos+"%";
|
|
||||||
});
|
|
||||||
|
|
||||||
var epub=ePub(calibre.bookUrl)
|
|
||||||
|
|
||||||
let progressDiv=document.getElementById("progress");
|
|
||||||
|
|
||||||
qFinished(()=>{
|
|
||||||
epub.locations.generate().then(()=> {
|
|
||||||
window.dispatchEvent(new Event('locationchange'))
|
|
||||||
});
|
|
||||||
})
|
|
@ -52,6 +52,32 @@ var reader;
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update progress percentage
|
||||||
|
let progressDiv = document.getElementById("progress");
|
||||||
|
reader.book.ready.then((()=>{
|
||||||
|
let locations_key = reader.book.key()+'-locations';
|
||||||
|
let stored_locations = localStorage.getItem(locations_key);
|
||||||
|
let make_locations, save_locations;
|
||||||
|
if (stored_locations) {
|
||||||
|
make_locations = Promise.resolve(reader.book.locations.load(stored_locations));
|
||||||
|
// No-op because locations are already saved
|
||||||
|
save_locations = ()=>{};
|
||||||
|
} else {
|
||||||
|
make_locations = reader.book.locations.generate();
|
||||||
|
save_locations = ()=>{
|
||||||
|
localStorage.setItem(locations_key, reader.book.locations.save());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
make_locations.then(()=>{
|
||||||
|
reader.rendition.on('relocated', (location)=>{
|
||||||
|
let percentage = Math.round(location.end.percentage*100);
|
||||||
|
progressDiv.textContent=percentage+"%";
|
||||||
|
});
|
||||||
|
reader.rendition.reportLocation();
|
||||||
|
progressDiv.style.visibility = "visible";
|
||||||
|
}).then(save_locations);
|
||||||
|
}));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} action - Add or remove bookmark
|
* @param {string} action - Add or remove bookmark
|
||||||
* @param {string|int} location - Location or zero
|
* @param {string|int} location - Location or zero
|
||||||
|
21
cps/static/js/reading/locationchange-polyfill.js
Normal file
21
cps/static/js/reading/locationchange-polyfill.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// register new event emitter locationchange that fires on urlchange
|
||||||
|
// source: https://stackoverflow.com/a/52809105/21941129
|
||||||
|
(() => {
|
||||||
|
let oldPushState = history.pushState;
|
||||||
|
history.pushState = function pushState() {
|
||||||
|
let ret = oldPushState.apply(this, arguments);
|
||||||
|
window.dispatchEvent(new Event('locationchange'));
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
let oldReplaceState = history.replaceState;
|
||||||
|
history.replaceState = function replaceState() {
|
||||||
|
let ret = oldReplaceState.apply(this, arguments);
|
||||||
|
window.dispatchEvent(new Event('locationchange'));
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('popstate', () => {
|
||||||
|
window.dispatchEvent(new Event('locationchange'));
|
||||||
|
});
|
||||||
|
})();
|
@ -215,6 +215,6 @@
|
|||||||
<script src="{{ url_for('static', filename='js/libs/screenfull.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/libs/screenfull.min.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/libs/reader.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/libs/reader.min.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/reading/epub.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/reading/epub.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/reading/epub-progress.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/reading/locationchange-polyfill.js') }}"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user