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
|
||||
return bookmarks, highlights, notes
|
||||
end
|
||||
|
||||
local file_sha256 = self:getFileSHA256()
|
||||
local total_pages = self.ui.document:getPageCount()
|
||||
local has_pages = self.ui.document.info.has_pages
|
||||
|
||||
for _, bm in ipairs(all_bookmarks) do
|
||||
local page_num = bm.page
|
||||
if type(page_num) == "string" and self.ui.document.info.has_pages == false then
|
||||
page_num = self.ui.document:getPageFromXPointer(page_num)
|
||||
end
|
||||
page_num = tonumber(page_num) or 0
|
||||
-- Thin-client policy: no per-annotation CRE lookups here (a
|
||||
-- getPageFromXPointer call each is the most expensive thing this
|
||||
-- loop can do on weak hardware). Percentages are arithmetic for
|
||||
-- paging documents and simply omitted for CRE documents — the
|
||||
-- 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 ""
|
||||
if type(chapter) == "table" then chapter = "" end
|
||||
|
||||
local entry = {
|
||||
chapter = chapter,
|
||||
@@ -849,9 +851,11 @@ function Bookhoard:collectAnnotations()
|
||||
pos1 = bm.pos1 or "",
|
||||
page = tostring(bm.page or ""),
|
||||
text = bm.text or "",
|
||||
percentage = Math.roundPercent(percentage),
|
||||
book_sha256 = file_sha256,
|
||||
}
|
||||
if percentage then
|
||||
entry.percentage = Math.roundPercent(percentage)
|
||||
end
|
||||
|
||||
local has_text = bm.text and bm.text ~= ""
|
||||
local has_notes = bm.notes and bm.notes ~= ""
|
||||
@@ -1159,9 +1163,23 @@ function Bookhoard:applyServerAnnotations(annotations)
|
||||
return pos0
|
||||
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 pos0 = server_entry.pos0 or ""
|
||||
if pos0 == "" then return end
|
||||
if not isValidPos0(pos0) then return end
|
||||
local idx = findLocalByPos0(pos0)
|
||||
if idx then
|
||||
local bm = local_bms[idx]
|
||||
|
||||
Reference in New Issue
Block a user