Merge Reader improvements
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
var reader;
|
||||
|
||||
(function() {
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
EPUBJS.filePath = calibre.filePath;
|
||||
@@ -10,7 +10,7 @@ var reader;
|
||||
|
||||
reader = ePubReader(calibre.bookUrl, {
|
||||
restore: true,
|
||||
bookmarks: calibre.bookmark ? [calibre.bookmark] : []
|
||||
bookmarks: calibre.bookmark ? [calibre.bookmark] : [],
|
||||
});
|
||||
|
||||
Object.keys(themes).forEach(function (theme) {
|
||||
@@ -54,29 +54,92 @@ var reader;
|
||||
|
||||
// Update progress percentage
|
||||
let progressDiv = document.getElementById("progress");
|
||||
reader.book.ready.then((()=>{
|
||||
let locations_key = reader.book.key()+'-locations';
|
||||
// Pages counter (virtual pages via EPUB locations)
|
||||
let pagesDiv = document.getElementById("pages-count");
|
||||
// Honor saved visibility preference for pages counter
|
||||
(function () {
|
||||
try {
|
||||
var pref = localStorage.getItem("calibre.reader.showPages");
|
||||
var show = pref === null ? true : pref === "true";
|
||||
if (pagesDiv)
|
||||
pagesDiv.style.visibility = show ? "visible" : "hidden";
|
||||
} catch (e) {}
|
||||
})();
|
||||
|
||||
reader.book.ready.then(() => {
|
||||
let locations_key = reader.book.key() + "-locations";
|
||||
// Key to persist last-read position for this book in localStorage
|
||||
let position_key = "calibre.reader.position." + reader.book.key();
|
||||
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));
|
||||
make_locations = Promise.resolve(
|
||||
reader.book.locations.load(stored_locations)
|
||||
);
|
||||
// No-op because locations are already saved
|
||||
save_locations = ()=>{};
|
||||
save_locations = () => {};
|
||||
} else {
|
||||
make_locations = reader.book.locations.generate();
|
||||
save_locations = ()=>{
|
||||
localStorage.setItem(locations_key, reader.book.locations.save());
|
||||
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);
|
||||
}));
|
||||
make_locations
|
||||
.then(() => {
|
||||
// Try to restore last position (CFI) from localStorage if present
|
||||
try {
|
||||
var _savedPos = localStorage.getItem(position_key);
|
||||
if (_savedPos) {
|
||||
try {
|
||||
var _posObj = JSON.parse(_savedPos);
|
||||
if (_posObj && _posObj.cfi) {
|
||||
// Display the saved CFI location
|
||||
try {
|
||||
reader.rendition.display(_posObj.cfi);
|
||||
} catch (e) {}
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
reader.rendition.on("relocated", (location) => {
|
||||
let percentage = Math.round(location.end.percentage * 100);
|
||||
progressDiv.textContent = percentage + "%";
|
||||
|
||||
// Pages based on generated EPUB locations (CFI positions)
|
||||
const cfi = location.start.cfi;
|
||||
const current =
|
||||
reader.book.locations.locationFromCfi(cfi) || 0; // 1-based index typically
|
||||
const total = reader.book.locations.length() || 0;
|
||||
|
||||
if (total > 0) {
|
||||
pagesDiv.textContent = current + "/" + total;
|
||||
pagesDiv.style.visibility = "visible";
|
||||
} else {
|
||||
pagesDiv.textContent = "";
|
||||
pagesDiv.style.visibility = "hidden";
|
||||
}
|
||||
|
||||
// Persist last position (CFI + percentage) to localStorage so reader can restore on next open
|
||||
try {
|
||||
var posObj = {
|
||||
cfi: location.start.cfi,
|
||||
percentage: location.start.percentage,
|
||||
};
|
||||
localStorage.setItem(
|
||||
position_key,
|
||||
JSON.stringify(posObj)
|
||||
);
|
||||
} catch (e) {}
|
||||
});
|
||||
reader.rendition.reportLocation();
|
||||
progressDiv.style.visibility = "visible";
|
||||
})
|
||||
.then(save_locations);
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {string} action - Add or remove bookmark
|
||||
@@ -85,26 +148,43 @@ var reader;
|
||||
function updateBookmark(action, location) {
|
||||
// Remove other bookmarks (there can only be one)
|
||||
if (action === "add") {
|
||||
this.settings.bookmarks.filter(function (bookmark) {
|
||||
return bookmark && bookmark !== location;
|
||||
}).map(function (bookmark) {
|
||||
this.removeBookmark(bookmark);
|
||||
}.bind(this));
|
||||
this.settings.bookmarks
|
||||
.filter(function (bookmark) {
|
||||
return bookmark && bookmark !== location;
|
||||
})
|
||||
.map(
|
||||
function (bookmark) {
|
||||
this.removeBookmark(bookmark);
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
var csrftoken = $("input[name='csrf_token']").val();
|
||||
|
||||
// Save to database
|
||||
$.ajax(calibre.bookmarkUrl, {
|
||||
method: "post",
|
||||
data: { bookmark: location || "" },
|
||||
headers: { "X-CSRFToken": csrftoken }
|
||||
headers: { "X-CSRFToken": csrftoken },
|
||||
}).fail(function (xhr, status, error) {
|
||||
alert(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Default settings load
|
||||
const theme = localStorage.getItem("calibre.reader.theme") ?? "lightTheme";
|
||||
selectTheme(theme);
|
||||
|
||||
// Restore saved font and font size after reader is ready
|
||||
reader.book.ready.then(() => {
|
||||
const savedFontSize = localStorage.getItem("calibre.reader.fontSize");
|
||||
if (savedFontSize) {
|
||||
reader.rendition.themes.fontSize(`${savedFontSize}%`);
|
||||
}
|
||||
|
||||
const savedFont = localStorage.getItem("calibre.reader.font");
|
||||
if (savedFont && window.selectFont) {
|
||||
window.selectFont(savedFont);
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user