Sync fixes for underpowered devices: thin client, server-heavy
- collectAnnotations no longer calls getPageFromXPointer per annotation (a CRE-engine lookup each — the most expensive thing the sync loop did on weak hardware). Paging documents compute percentage arithmetically; CRE documents omit it entirely and the server derives it from the locator against the actual book. - chapter/page are sent raw; the server's tolerant types accept strings, empty strings, and CRE xpointers in the page field. Previously a single annotation with chapter:'' failed the ENTIRE progress push with a 400, silently killing progress sync too. - applyServerAnnotations validates pos0 before applying: rolling documents require '/body/...' xpointers, paging documents numeric pages. Unplaceable locators are skipped instead of becoming junk local bookmarks that would re-push as duplicates.
This commit is contained in:
@@ -827,19 +827,21 @@ function Bookhoard:collectAnnotations()
|
|||||||
if not all_bookmarks then
|
if not all_bookmarks then
|
||||||
return bookmarks, highlights, notes
|
return bookmarks, highlights, notes
|
||||||
end
|
end
|
||||||
|
|
||||||
local file_sha256 = self:getFileSHA256()
|
local file_sha256 = self:getFileSHA256()
|
||||||
local total_pages = self.ui.document:getPageCount()
|
local total_pages = self.ui.document:getPageCount()
|
||||||
|
local has_pages = self.ui.document.info.has_pages
|
||||||
|
|
||||||
for _, bm in ipairs(all_bookmarks) do
|
for _, bm in ipairs(all_bookmarks) do
|
||||||
local page_num = bm.page
|
-- Thin-client policy: no per-annotation CRE lookups here (a
|
||||||
if type(page_num) == "string" and self.ui.document.info.has_pages == false then
|
-- getPageFromXPointer call each is the most expensive thing this
|
||||||
page_num = self.ui.document:getPageFromXPointer(page_num)
|
-- loop can do on weak hardware). Percentages are arithmetic for
|
||||||
end
|
-- paging documents and simply omitted for CRE documents — the
|
||||||
page_num = tonumber(page_num) or 0
|
-- server derives them from the locator against the actual book.
|
||||||
|
local page_num = tonumber(bm.page) or 0
|
||||||
|
local percentage = has_pages and total_pages > 0 and (page_num / total_pages) or nil
|
||||||
|
|
||||||
local percentage = total_pages > 0 and (page_num / total_pages) or 0
|
|
||||||
local chapter = bm.chapter or ""
|
local chapter = bm.chapter or ""
|
||||||
|
if type(chapter) == "table" then chapter = "" end
|
||||||
|
|
||||||
local entry = {
|
local entry = {
|
||||||
chapter = chapter,
|
chapter = chapter,
|
||||||
@@ -849,9 +851,11 @@ function Bookhoard:collectAnnotations()
|
|||||||
pos1 = bm.pos1 or "",
|
pos1 = bm.pos1 or "",
|
||||||
page = tostring(bm.page or ""),
|
page = tostring(bm.page or ""),
|
||||||
text = bm.text or "",
|
text = bm.text or "",
|
||||||
percentage = Math.roundPercent(percentage),
|
|
||||||
book_sha256 = file_sha256,
|
book_sha256 = file_sha256,
|
||||||
}
|
}
|
||||||
|
if percentage then
|
||||||
|
entry.percentage = Math.roundPercent(percentage)
|
||||||
|
end
|
||||||
|
|
||||||
local has_text = bm.text and bm.text ~= ""
|
local has_text = bm.text and bm.text ~= ""
|
||||||
local has_notes = bm.notes and bm.notes ~= ""
|
local has_notes = bm.notes and bm.notes ~= ""
|
||||||
@@ -1159,9 +1163,23 @@ function Bookhoard:applyServerAnnotations(annotations)
|
|||||||
return pos0
|
return pos0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function isValidPos0(pos0)
|
||||||
|
-- Rolling (CRE) documents address bookmarks/highlights by xpointer;
|
||||||
|
-- paging documents (PDF/comics/DjVu) by page number. Anything else
|
||||||
|
-- (a raw "cfi:" locator, an epubcfi(...) string, a JSON anchor, …)
|
||||||
|
-- cannot be placed in this document and must not become a local
|
||||||
|
-- bookmark: it could never be matched again and would be re-pushed
|
||||||
|
-- to the server as a junk duplicate on the next sync.
|
||||||
|
if pos0 == "" then return false end
|
||||||
|
if has_pages then
|
||||||
|
return tonumber(pos0) ~= nil
|
||||||
|
end
|
||||||
|
return pos0:sub(1, 7) == "/body/"
|
||||||
|
end
|
||||||
|
|
||||||
local function addOrUpdate(server_entry, has_text)
|
local function addOrUpdate(server_entry, has_text)
|
||||||
local pos0 = server_entry.pos0 or ""
|
local pos0 = server_entry.pos0 or ""
|
||||||
if pos0 == "" then return end
|
if not isValidPos0(pos0) then return end
|
||||||
local idx = findLocalByPos0(pos0)
|
local idx = findLocalByPos0(pos0)
|
||||||
if idx then
|
if idx then
|
||||||
local bm = local_bms[idx]
|
local bm = local_bms[idx]
|
||||||
|
|||||||
Reference in New Issue
Block a user