feat(koreader): rebuild the plugin interface and fix four-way annotation sync

Squash of feat/koreader-widget-board. KOReader plugin 2.0.0 gets the widget-board dashboard, redesigned
book details, menus, lists and dialogs, Decor page and reading companions. Highlights, notes and bookmarks
now stay in step across web, Kobo, KOReader and the phones (defects D-00 to D-20, migration 0121), and
reading progress and narration hand off cleanly between devices.
This commit is contained in:
neon
2026-10-19 21:04:23 +00:00
parent 7202a59afc
commit 80244ea4e2
349 changed files with 66312 additions and 8386 deletions
@@ -15,12 +15,22 @@ package.loaded["ffi/util"] = {
}
local confirm_boxes = {}
package.loaded["ui/widget/confirmbox"] = {
new = function(_, opts)
table.insert(confirm_boxes, opts)
return opts
local shown_texts = {}
-- The prompt is the This book sheet; its Jump and Stay stand in for a
-- confirm box's OK and Cancel.
package.loaded["bookorbit_book_sheet"] = {
openPrompt = function(_plugin, prompt)
table.insert(confirm_boxes, {
prompt = prompt,
ok_callback = prompt.on_jump,
cancel_callback = prompt.on_stay or function() end,
})
end,
}
package.loaded["bookorbit_toast"] = {
show = function(text) if shown_texts then table.insert(shown_texts, text) end end,
error = function(text) if shown_texts then table.insert(shown_texts, text) end end,
}
package.loaded["device"] = { model = "Kobo Libra" }
local events = {}
@@ -40,7 +50,6 @@ package.loaded["ui/network/manager"] = {
willRerunWhenConnected = function() return false end,
}
local shown_texts = {}
package.loaded["ui/uimanager"] = {
show = function(_, message)
table.insert(shown_texts, message.text)
@@ -201,4 +210,29 @@ local same_position = makePlugin(restored_body, { local_percent = 0.75, local_pr
same_position:getProgress(false, true)
assertEqual(#events, 0, "same-position explicit pull remains idempotent")
for _, interactive in ipairs({ false, true }) do
local position = { local_progress = "/body/DocFragment[6]/body" }
local moving = makePlugin(restored_body, position)
moving.settings.sync_forward = moving.SYNC_STRATEGY.SILENT
moving.newClient = function()
return { getProgress = function()
position.local_progress = "/body/DocFragment[13]/body"
return restored_body
end }
end
moving:getProgress(false, interactive)
assertEqual(#events, 0, "late pull cannot undo navigation during the request")
assertEqual(#confirm_boxes, 0, "late pull cannot prompt for an obsolete local position")
local replaced = makePlugin(restored_body)
replaced.newClient = function()
return { getProgress = function()
replaced.ui.document = nil
return restored_body
end }
end
replaced:getProgress(false, interactive)
assertEqual(#events, 0, "late pull cannot navigate a closed document")
end
print("bookorbit_progress_reset_test.lua: ok")