diff --git a/main.lua b/main.lua index 7d88fbf..cdc401c 100644 --- a/main.lua +++ b/main.lua @@ -1545,7 +1545,7 @@ function Bookhoard:applyServerAnnotations(annotations) end local has_pages = self.ui.document.info.has_pages - local function findLocal(server_entry) + local function findLocal(server_entry, has_text) -- Identity match by dedup key: survives pos0 drift (improved -- server conversion) and, crucially, never cross-matches a -- DIFFERENT annotation that merely shares the position. @@ -1556,7 +1556,38 @@ function Bookhoard:applyServerAnnotations(annotations) return i end end - return nil -- keyed but not present: a real new entry + -- No key holder, but a keyed serve may still be THIS device's + -- own creation echoed back: the server stamped a computed key + -- on our push before we ever pulled one. Adopt a keyless local + -- annotation of the same kind at the identical pos0 + -- (addOrUpdate stamps + updates it) instead of applying a + -- duplicate beside it. Keyed local entries are never + -- pos0-matched, so distinct annotations sharing a position + -- cannot cross-match. + local pos0 = server_entry.pos0 or "" + if pos0 ~= "" then + for i, bm in ipairs(entries) do + if not bm.bookhoard_dedup_key then + local is_highlight + if model == "v2" then + is_highlight = bm.drawer ~= nil + else + is_highlight = bm.notes ~= nil and bm.notes ~= "" + end + if is_highlight ~= has_text then + -- Wrong kind: a page bookmark at the same spot + -- is a different annotation, never an echo. + else + local p = bm.pos0 + if type(p) == "table" then p = tostring(p.page or "") end + if p == pos0 then + return i + end + end + end + end + end + return nil -- genuinely absent: a real new entry end -- Legacy serve (no key): fall back to pos0 matching. local pos0 = server_entry.pos0 or "" @@ -1631,7 +1662,7 @@ function Bookhoard:applyServerAnnotations(annotations) -- locators return above and are never tracked — absence of an -- annotation this device never held is not a deletion. local kind = has_text and "highlight" or "bookmark" - local idx = findLocal(server_entry) + local idx = findLocal(server_entry, has_text) if idx then local bm = entries[idx] -- Legacy pos0 match on a device-native entry: stamp the key so