collectBookData put getLastProgress() directly into the epubcfi field
for every document. For paging documents (has_pages == true: PDF, CBZ,
CBR, CB7, CBT, DjVu) that value is the current page as a *number*, so
the payload carried "epubcfi": 5 (a JSON number). The server types
KOReaderBookProgress.Epubcfi as *string, and the strict JSON binder
rejected it with a 400 ("cannot unmarshal number into ... epububcfi of
type string"), which the plugin surfaced as the misleading
"Failed to push progress. Check your network connection." Reflowable
EPUBs were unaffected because CREngine returns an xpointer string.
Only set epubcfi for rolling (reflowable) documents. Paging documents
carry their position in the numeric page/total_pages fields, which the
server already treats as the canonical locator for fixed-layout/comic
formats. The pull path already falls back to progress.page, so restore
keeps working.
Lua's json.encode produces {} for empty tables instead of [].
Use json.util.InitArray to mark tables as arrays so they encode
correctly as [] for authors, bookmarks, highlights, notes, and books.
- Append ?token= auth param to OPDS catalog URL
- Replace any existing stale Bookhoard entry (with or without token)
- Hot-update OPDS plugin's in-memory servers table so catalog
appears immediately without restarting KOReader
Writes directly to KOReader's opds.lua settings so the user
doesn't have to type the long URL. Also updates the manual
menu item to auto-configure instead of showing the URL.
Instead of showing a long auth URL that's impractical to type on
e-ink, tell users to open their Bookhoard web UI and approve from
Device Management. Uses persistent InfoMessage (no timeout) so
the message stays visible while they switch devices.