Fix crash on pull: AnnotationsModified payload must be a table
Event:new("AnnotationsModified", nil) delivered a nil payload to
every handler; ReaderThumbnail:resetCachedPagesForBookmarks does
#annotations on it and crashed KOReader the moment a pull applied
annotations (native KOReader always dispatches this event with a
table payload).
applyServerAnnotations now collects per-changed-item payloads and
dispatches them after applying, mirroring the native add/update/
remove dispatch shapes exactly: {entry, index_modified=index} for
adds (index from annotation:addItem), {bm} for content updates, and
{removed, index_modified=-index} for tombstone removals. This keeps
ReaderView's page-level highlight-box cache invalidation AND its
cached box-index shifting consistent, so mid-session pulls both
paint immediately and keep tap-to-edit associations correct.
Harness-verified: every dispatched payload is a table (explicit
crash-regression assertion simulating ReaderThumbnail's handler),
per-item index_modified values are correct, and all prior behaviors
(color flow, echo suppression, dedup round-trip) still hold.
This commit is contained in:
@@ -1232,6 +1232,10 @@ function Bookhoard:applyServerAnnotations(annotations)
|
||||
if not model then return end
|
||||
|
||||
local changed = false
|
||||
local notify_events = {}
|
||||
local function notify(ev)
|
||||
notify_events[#notify_events + 1] = ev
|
||||
end
|
||||
local has_pages = self.ui.document.info.has_pages
|
||||
|
||||
local function findLocal(server_entry)
|
||||
@@ -1321,6 +1325,7 @@ function Bookhoard:applyServerAnnotations(annotations)
|
||||
if cur_text ~= srv_text or cur_note ~= srv_notes then
|
||||
setFields(bm, srv_text, srv_notes)
|
||||
if server_entry.color and server_entry.color ~= "" then bm.color = server_entry.color end
|
||||
notify({ bm })
|
||||
changed = true
|
||||
end
|
||||
elseif model == "v2" then
|
||||
@@ -1359,7 +1364,8 @@ function Bookhoard:applyServerAnnotations(annotations)
|
||||
else
|
||||
if srv_text ~= "" then entry.note = srv_text end -- bookmark label
|
||||
end
|
||||
self.ui.annotation:addItem(entry)
|
||||
local index = self.ui.annotation:addItem(entry)
|
||||
notify({ entry, index_modified = index })
|
||||
changed = true
|
||||
else
|
||||
local entry = {
|
||||
@@ -1435,6 +1441,7 @@ function Bookhoard:applyServerAnnotations(annotations)
|
||||
local cur_text = bm and (getFields(bm)) or ""
|
||||
if idx and cur_text ~= "" then
|
||||
table.remove(entries, idx)
|
||||
notify({ bm, index_modified = -idx })
|
||||
changed = true
|
||||
end
|
||||
end
|
||||
@@ -1444,7 +1451,9 @@ function Bookhoard:applyServerAnnotations(annotations)
|
||||
for _, del in ipairs(annotations.deleted_bookmarks) do
|
||||
local idx = findLocalByTombstone(del, false)
|
||||
if idx then
|
||||
local removed = entries[idx]
|
||||
table.remove(entries, idx)
|
||||
notify({ removed, index_modified = -idx })
|
||||
changed = true
|
||||
end
|
||||
end
|
||||
@@ -1462,9 +1471,14 @@ function Bookhoard:applyServerAnnotations(annotations)
|
||||
-- ReaderView caches each rendered page's highlight boxes and only
|
||||
-- invalidates them on AnnotationsModified — without this, applied
|
||||
-- annotations don't paint until restart despite the repaint.
|
||||
-- A non-table payload clears the whole cache (per-item payloads
|
||||
-- only remove the pages of the listed items).
|
||||
self.ui:handleEvent(Event:new("AnnotationsModified", nil))
|
||||
-- Payloads MUST be tables: ReaderThumbnail iterates them, and a
|
||||
-- nil payload crashed KOReader (#nil) on pull. Per-item payloads
|
||||
-- with index_modified mirror the native add/update/remove
|
||||
-- dispatches exactly (page-level cache invalidation + cached box
|
||||
-- index shifting).
|
||||
for _, ev in ipairs(notify_events) do
|
||||
self.ui:handleEvent(Event:new("AnnotationsModified", ev))
|
||||
end
|
||||
if self.ui.dialog then
|
||||
UIManager:setDirty(self.ui.dialog, "ui")
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user